perm filename IOELEV.PAL[DLN,MRC] blob sn#306130 filedate 1977-09-14 generic text, type T, neo UTF8
	.TITLE IOELEVEN

	.SBTTL DEFINITIONS

A=%0		;TEMP/ARG/CHAR
B=%1		;TEMP/ARG
C=%2		;TEMP/ARG
D=%3		;TEMP/ARG
H=%4		;USUALLY INDEX IN HARDWARE UNIT TABLES
I=%5		;USUALLY LINE NUMBER TIMES 2
SP=%6		;STACK POINTER
PC=%7		;PROGRAM POINTER
PS=177776	;PROGRAM STATUS
SWR=177570	;SWITCHES

.MACRO RTI
.ENDM ;FUCKING PALX!

RTI=RTT		;11/40 HARDWARE MISFEATURE

.IF P1
.PRINT /MACHINE NAME = /
.TTYMAC MNAM
%TTYFLG==%TTYFLG+1
.PRINT /MNAM
/
%TTYFLG==%TTYFLG-1
.MACRO .IFM MCHN		;REFERS TO PDP11 NAME
.IF IDN MCHN,MNAM
.ENDM .IFM
.MACRO MCONDX MCHN		;REFERS TO ITS SYSTEM NAME, USUALLY THE SAME
.IF IDN MCHN,MNAM
.ENDM MCONDX
.MACRO FUBAR
.ENDC
.ENDC
.ENDM FUBAR
.MACRO MNAME BODY		;INSERT ITS SYSTEM NAME INTO BODY IN PLACE OF "MCHN"
.IRP MCHN,<MNAM>
BODY
.ENDM
.ENDM MNAME
.ENDM ;TTYMAC
.ENDC ;P1

VERSION==%FNAM2

.IFM MC-DL			;MC'S DL-10 PDP11
.MACRO MCONDX MCHN
.IF IDN MCHN,MC
.ENDM MCONDX
.MACRO FUBAR
.ENDC
.ENDM FUBAR
.MACRO MNAME BODY
.IRP MCHN,<MC>
BODY
.ENDM
.ENDM MNAME

DL10P==1	;HAS DL10
DTE20P==0	;DOES NOT HAVE DTE20
NFTTY==22	;2 * # OF FIRST TTY THIS 11
NDHS==1		;NUMBER OF DH11'S
NDHUN==0	;NUMBER OF UNUSED DH11 LINES
DHIBAS==320	;DH11 INTERRUPT VECTOR BASE
NDLS==1		;NUMBER OF DL11'S
CTYP==0		;FIRST DL11 NOT T00 (CTY)
NMPTYS==11.	;NUMBER OF TTYS ON MULTIPLEXED LINE
MPXIDX==2*27	;TTY INDEX OF LINE THAT MULTIPLEXED TTYS RUN OVER
MDMP==1		;HAS DM11BB MODEM SCANNER
GOULDP==0	;DOESN'T HAVE GOULD LPT (ANYMORE)
MAXBSZ==250.	;MAXIMUM TYPEOUT BUFFER SIZE
.MACRO ASPIRP BODY	;DEFINE LINE NUMBERS WITH AUTOSPEED
.IRP N,<4,5,6,7>
BODY
.ENDM
.ENDM
.ENDC ;MC-DL

.IFM MC		;MC CONSOLE 11
DL10P==0	;DOES NOT HAVE DL10
DTE20P==1	;HAS DTE20
NFTTY==0	;2 * # OF FIRST TTY THIS 11
NDHS==1		;NUMBER OF DH11'S
NDHUN==8	;NUMBER OF UNUSED DH11 LINES
DHIBAS==310	;DH11 INTERRUPT VECTOR BASE
NDLS==1		;NUMBER OF DL11'S
CTYP==1		;FIRST DL11 IS T00 (CTY)
NMPTYS==0	;NUMBER OF TTYS THAT GO THROUGH MULTIPLEXED LINE (NONE)
MDMP==1		;HAS DM11BB MODEM SCANNER (REALLY DH11AD)
GOULDP==0	;DOESN'T HAVE GOULD LPT
MAXBSZ==250.	;MAXIMUM TYPEOUT BUFFER SIZE

.MACRO ASPIRP BODY	;DEFINE LINE #S WITH AUTOSPEED
.IRP N,<3,4,5,6,7>
	BODY
.ENDM
.ENDM ASPIRP

TKS==177560
TKB==177562
TPS==177564
TPB==177566
.ENDC ;MC

.IIF NDF NDHS, .ERROR MACHINE NAME NOT RECOGNIZED

.IIF NZ DL10P, .IIF Z NFTTY, .ERROR TTY # 0 DOESN'T WORK WITH DL10 PROTOCOL

;ASSIGN TTY INDICES, HARDWARE INDICES, ETC.

TX==NFTTY	;TTY INDEX
HX==0		;HARDWARE INDEX
NCT==0		;NUMBER OF TTYS

;SYSTEM CONSOLE (OUT OF ORDER)
.IFNZ CTYP
	TX==TX+2
	NCT==NCT+1
.ENDC

;DH11 LINES
	NFDHTY==TX
	TX==TX+<32.*NDHS>
	NCT==NCT+<16.*NDHS>
	HX==HX+<2*NDHS>
	NLDHHX==HX-2		;UNITS 0-NLDHHX INCLUSIVE ARE DH11S

	TX==TX-<2*NDHUN>	;COMPENSATE FOR UNUSED LINES
	NLDHTY==TX-2		;LAST DH11 LINE INCLUSIVE
	NCT==NCT-NDHUN

;DL11 LINES
	NFDLTY==TX
	NFDLHX==HX
	TX==TX+<2*NDLS>-<2*CTYP>
	HX==HX+<2*NDLS>
	NLDLHX==HX-2
	NCT==NCT+NDLS-CTYP

;MULTIPLEXOR LINES
	NFMPTY==TX
	MPKHWR==HX
	TX==TX+<2*NMPTYS>
	HX==HX+2
	NCT==NCT+NMPTYS

NLTTY==NFTTY+<2*NCT>	;2 * # OF FIRST TTY NOT THIS 11
LASTTY==NLTTY-2		;LAST VALID TTY INDEX

.IFNZ MDMP	;DM11-BB MODEM SCANNER

MDMCSR=170500
		;1.1-1.4 MODEM CHANNEL #
 MDMBSY==20	;1.5 SCAN BUSY (R.O.)
 MDMSCN==40	;1.6 SCANNER ON
 MDMIEN==100	;1.7 INTERRUPT ENABLE
 MDMDON==200	;1.8 DONE - SCANNER HAS FOUND SOMETHING
 MDMSTP==400	;1.9 STEP SCANNER TO NEXT LINE (W.O.) 1.2 USEC.
		;2.1 MAINTENANCE MODE
 MDMCLR==2000	;2.2 CLEAR RTS, DTR, SEC TX, LINE EN FOR ALL LINES (W.O.)
 MDMCSN==4000	;2.3 CLEAR SCAN - CLEAR CSR AND MODEM STATUS MEMORY (W.O.) 19 USEC
 MDM2RX==10000	;2.4 SECONDARY RECIEVE CHANGED ON SELECTED MODEM (R.O.)
 MDMCTS==20000	;2.5 CLEAR TO SEND CHANGED ON SELECTED MODEM (R.O.)
 MDMCAR==40000	;2.6 CARRIER DETECT CHANGED ON SELECTED MODEM (R.O.)
 MDMRNG==100000	;2.7 RING CHANGED ON SELECTED MODEM (R.O.)
MDMLSR=170502	;STATUS OF SELECTED LINE
 LINENB==1	;1.1 ENABLE SCANNING OF LINE
 LINDTR==2	;1.2 DATA TERMINAL READY
 LINRQS==4	;1.3 REQUEST TO SEND (FORCE BUSY ON 103E)
 LIN2TX==10	;1.4 SECONDARY TRANSMIT
 LIN2RX==20	;1.5 SECONDARY RECEIVE (R.O.)
 LINCTS==40	;1.6 CLEAR TO SEND (R.O.)
 LINCAR==100	;1.7 CARRIER DETECT (R.O.)
 LINRNG==200	;1.8 RING (R.O.)
.ENDC ;MDMP

; KW11-L LINE FREQ CLOCK

LKS=177546	;1.8 CLOCK FLAG
		;1.7 INTER ENB
HNGDLY==3*60.	;CLEAR TO SEND OFF FOR 3 SECONDS => HANGUP

.IFNZ GOULDP
;DEFINITIONS FOR GOULD LPT

GLPCSR=166000	;COMMAND STATUS REGISTER (NONSTANDARD)
 ;COMMAND CODES
 %GCFF==0	;TOP-OF-FORM COMMAND
 %GCGRF==1	;GRAPHIC MODE COMMAND
 %GCCUT==2	;CUT COMMAND (NO CUTTER ON THIS MACHINE, THOUGH)
 %GCON==3	;TURN PRINTER ON
 %GCOFF==4	;TURN PRINTER OFF
 %GCLSL==5	;LAST LINE (GRAPHIC MODE).  => 2 MORE SCAN LINES.
 %GCION==6	;INTERRUPT ON
 %GCIOF==7	;INTERRUPT OFF
 %GCADV==201	;ADVANCE ONE LINE
 ;STATUS BITS
 %GSNRD==400	;NOT READY
 %GSDON==2000	;TRANSFER COMPLETE
 %GSBSY==4000	;BUSY
 %GSVAC==10000	;VACUUM FAULT
 %GSPAP==20000	;PAPER LOW
 %GSTIM==40000	;TIMEOUT
 %GSERR==50400	;ALL ERROR BITS

GLPWC=166002	;NEGATIVE WORD COUNT REG

GLPCA=166004	;CURRENT ADDRESS REG

GLPBSZ==132.	;BUFFER SIZE (# CHARS PER LINE)

NGLPBF==7	;NUMBER OF BUFFERS
 GB.STA==0	;BUFFER STATE - DON'T CHANGE ORDER OF %GB CODES
  %GBIDL==0	;0 IDLE
  %GBMP==2	;2 ACTIVE AT M.P. LEVEL
  %GBWRT==4	;4 IN WRITE QUEUE
  %GBPI==6	;6 ACTIVE AT P.I. LEVEL
  %GBDMA==8	;8 ACTIVE AT D.M.A. LEVEL
 GB.NXT==2	;CIRC POINTER TO NEXT BUFFER
 GB.FF==4	;IF NON-ZERO, FF BEFORE THIS BUFFER
 GB.NL==6	;NUMBER OF BLANK LINES BEFORE THIS BUFFER
 GB.PNT==10	;-> NEXT BYTE TO INSERT
 GB.DAT==12	;DATA BEGINS HERE
 GB.LEN==GB.DAT+GLPBSZ	;TOTAL NUMBER OF BYTES PER BUFFER

.ENDC ;GOULDP

;STANDARD MACROS

.MACRO PUSH X
.IRP Y,<X>
	MOV Y,-(SP)
.ENDM
.ENDM

.MACRO POP X
.IRP Y,<X>
	MOV (SP)+,Y
.ENDM
.ENDM

.MACRO CALL X
	JSR PC,X
.ENDM

.MACRO RET
	RTS PC
.ENDM

.MACRO SETOM LOC
 ZZ===%COMPAT		;DON'T CARE WHETHER .+2 OR .+4 GETS STORED
 %COMPAT===0
	MOV PC,LOC
 %COMPAT===ZZ
.ENDM

.MACRO MASK LEVEL
	PUSH PS
	MOV #<LEVEL>←5,PS
.ENDM

.MACRO UNMASK
	POP PS
.ENDM

.MACRO W
.=.+2
.ENDM

.MACRO T TAG	;usage is T TAG: <crlf> STMNT
.=.-NFTTY
TAG
.=.+NFTTY
.ENDM

.MACRO CONC A,B,C,D,E,F,G
A'B'C'D'E'F'G
.ENDM

.MACRO INFORM A,B,C,D,E,F,G
.IF P1
.PRINT /A'B'C'D'E'F'G
/
.ENDC
.ENDM

.MACRO MSG X
.NCHR ZZ,↑\X\
	.WORD ZZ
	.ASCII \X\
	.EVEN
.ENDM

.MACRO .IREPT N,BOD
.REPT N
BOD
.ENDR
.ENDM
.IFNZ DL10P
	.SBTTL DL10 CONTROL AREA

ZZ==.
.=100000

DLXCSR: W	;DL10 11-SIDE CONTROL & STATUS REG
		;1.1-1.2 PIA
 DLXIEN==4	;1.3 ENABLE DLX11I TO INTERRUPT
 DLXEEN==10	;1.4 ENABLE ERRORS TO INTERRUPT
		;1.5 UNUSED
 DLXPRT==40	;1.6 PORT ENABLE (R.O.)
 DLXZWC==100	;1.7 CLEAR DLXWCO (W.O.)
 DLXWCO==200	;1.8 WORD COUNT OVERFLOW
 DLXZPA==400	;1.9 CLEAR DLXPAR (W.O.)
 DLXPAR==1000	;2.1 PAR ERR IN 10 MEM
 DLXZNX==2000	;2.2 CLEAR DLXNXM (W.O.)
 DLXNXM==4000	;2.3 NXM IN 10 MEM
 DLXZ10==10000	;2.4 CLEAR DLX10I (W.O.)
 DLX10I==20000	;2.5 INTERRUPT PDP10
 DLXZ11==40000	;2.6 CLEAR DLX11I (W.O.)
 DLX11I==100000	;2.7 INTERRUPT PDP11

VERS:	W	;.BYTE FIRST LINE, # OF LINES
		;SET BY -10.  USED TO CHECK CONSISTENCY.

DLXUP:	W	;CHECK FOR UP-NESS IN BOTH DIRECTIONS
		;INCREMENTED BY 11 EVERY 1/60 SECOND, SETOM'ED BY 10 EVERY 1/2 SEC.

TTYST:	W	;LINE# TO START OUTPUT ON (I.E. SET OUTPUT DONE)
		;SET BY 10, CLEARED BY 11

TYILIN:	W	;TYPEIN STATUS WORD - LINE NUMBER
		;SET BY 11, CLEARED BY 10 - INTERRUPTS 10
TYICHR:	W	;TYPEIN CHARACTER - GOES WITH PRECEDING WORD

TYOSTS:	W	;STATUS WORD (OUTPUT DONE LINE #)
		;SET BY 11, CLEARED BY 10 - INTERRUPTS 10
TYOBSZ:	W	;BUFFER SIZE FOR LINE WITH OUTPUT DINE (SET BY 11)

TYOPNT:	W	;BUFFER POINTER FOR TTY OUTPUT
		;SET BY 10
TYOCNT:	W	;BUFFER LENGTH FOR TTY OUTPUT
		;SET BY 10
TYOLIN:	W	;LINE NUMBER FOR TTY OUTPUT
		;SET BY 10, CLEARED BY 11

HNGLIN:	W	;0000NN - LINE # NN HUNG UP
		;01RTNN - LINE # NN HAS SPEED RCV=R, XMT=T (SEE TTYTYP FOR CODES)
		;SET BY 11, CLEARED BY 10 - INTERRUPTS 10

LPRLIN:	W	;LINE NUMBER FOR SETTING LINE PARAMETERS
		;SET BY 10, CLEARED BY 11
LPRLPR:	W	;DH11 LPR REGISTER FOR SETTING LINE PARAMETERS
		;SET BY 10
LPRBSZ:	W	;BUFFER SIZE FOR SETTING LINE PARAMETERS
		;SET BY 10

EXDSTS:	W	;STATUS WORD (EXAMINE/DEPOSIT 11 CORE)
		;1 = EXAMINE, 2 = DEPOSIT
		;SET BY 10, CLEARED BY 11
EXDADR:	W	;ADDRESS FOR ABOVE
		;SET BY 10
EXDDAT:	W	;DATA WORD FOR ABOVE
		;SET BY 10 (DEPOSIT) OR 11 (EXAMINE)

GLPPTR:	W	;BUFFER POINTER FOR GOULD OUTPUT
GLPCTR:	W	;NUMBER OF BYTES YET TO BE GOBBLED
GLPTER:	W	;ERROR STATUS, SET BY 11
GLPGRF:	W	;GRAPHIC MODE IF NON-ZERO, SET BY 10

;↑ ADD MORE HERE, E.G. IMP
DLXHGH::
.=ZZ
.ENDC ;DL10P
.IFNZ DTE20P
	.SBTTL DTE20 CONTROL AREA

;LOCATIONS 400-437 ARE JUST BETWEEN US AND ITS
;LOCATIONS 440-457 ARE KNOWN ABOUT BY KLDCP ALSO

;EPTDDT==441	;START ADDRESS OF PDP10 NON TIME SHARING DDT
DTEFLG==444	;NON TIME SHARING TYPEIN/TYPEOUT DONE FLAG (SET BY 11, CLEARED BY 10)
DTEF11==450	;USED BY NON TIMESHARING TYPEIN COMMAND TO RETURN THE CHAR (SET BY 11)
DTECMD==451	;NON TIME SHARING COMMAND (SET BY 10)
;COMMANDS THAT CAN GO IN DTECMD:
 ;0-377 CHAR TO BE TYPED OUT
 %DTTYI==3400	;TYPE IN, CHAR RETURNED IN DTEF11
 %DTCLN==1001	;60 CYCLE CLOCK ON
 %DTCLF==1000	;60 CYCLE CLOCK OFF
 ;THERE ARE MILLIONS OF OTHERS, BUT WHO NEEDS 'EM?
DTECLK==445	;60 CYCLE CLOCK FLAG (SET BY 11, CLEARED BY 10)
;DTESWR==457	;SIMULATED SWITCH REGISTER (SET BY 11)

;THE FOLLOWING LOCATIONS ARE ONLY USED IN TIME SHARING AND NOT KNOWN ABOUT BY KLDCP

DTEVER==400	;I/O VERSION NUMBER.  .BYTE FIRST LINE, NUMBER OF LINES.
		;SET BY 10, CHECKED BY 11

DTECHK==401	;INCREMENTED BY 11 60 TIMES PER SECOND, SETOMED BY 10 EVERY 1/2 SECOND
		;USED TO CHECK THAT 10 IS GETTING INTERRUPTS OK

DTEINP==402	;CONTROLS "BYTE TRANSFERS" FROM 11 TO 10 (INPUT DIRECTION).
		;SET BY 10 TO REQUEST A TRANSFER, SETOM'ED BY 11 WHEN XFER COMPLETE.
		;10 SHOULD SET UP DTEBPI IN EPT AND DO DATAO DTE, BEFORE SETTING DTEINP.
		;SEE COMMENTS BELOW DTEOUT FOR WHAT GOES IN DTEINP.
DTEOUT==403	;CONTROLS "BYTE TRANSFERS" FROM 10 TO 11 (OUTPUT DIRECTION).
		;SET BY 10 TO REQUEST A TRANSFER, SETOM'ED BY 11 WHEN TRANSFER STARTS.
		;EACH SIDE KNOWS WHEN TRANSFER IS IN PROGRESS, DOESN'T TRY TO START
		; ANOTHER UNTIL IT HAS RECEIVED HARDWARE TRANSFER-DONE INTERRUPT.
		;10 SHOULD SET UP DTEBPO IN EPT BEFORE SETTING DTEOUT.
		;RH IS #BYTES EXPECTED, LH IS COMMAND+LINE#.  COMMANDS ARE:
 %DTTYO==1000	;TELETYPE OUTPUT
 %DTETI==2000	;ETHERNET INPUT
 %DTETO==3000	;ETHERNET OUTPUT
 ;↑ ADD MORE COMMANDS HERE.   NOTE: THE 4.1 BIT IS 1 FOR OUTPUT, 0 FOR INPUT.

DTELSP==404	;LINE# TO SET SPEED OF (SET BY 10, SETOMED BY 11)
DTELPR==405	;DH11 LINE-PARAMETER-REGISTER,,BUFFER SIZE

DTEOST==406	;LINE# TO START OUTPUT ON (SET OUTPUT DONE).  (SET BY 10, SETOMED BY 11)

	;407 NOT USED

DTETYI==410	;TELETYPE INPUT
		;LH=LINE#, RH=CHAR RECEIVED.  (SET BY 11, SETOM'ED BY 10)

DTEODN==411	;TELETYPE OUTPUT DONE
		;LH=LINE#, RH=BUFFER SIZE.  (SET BY 11, SETOM'ED BY 10)

DTEHNG==412	;HANGUP/DIALIN WORD  (SET BY 11, SETOM'ED BY 10)
		;0000NN - LINE # NN HUNG UP
		;01RTNN - LINE # NN HAS SPEED RCV=R, XMT=T (SEE TTYTYP FOR CODES)

;↑ ADD MORE HERE, NOT TO EXCEED LOCATION 437
;.IFNZ DTE20P

;IOELEVEN RESIDES IN THE BOTTOM 14K OF THE CONSOLE PDP11, ALONG WITH 11DDT.
;I.E. LOCATIONS 0-70000.  BE SURE TO USE .;11DDT 14K VERSION OF DDT.
;THE UPPER 14K CONTAIN KLDCP.  THE FOLLOWING CALLS TO KLDCP ARE USED.
;THEY RETURN WITH C-BIT SET IF THEY LOSE (MICROCODE HUNG).

;NOTE: KLDCP ENJOYS CLOBBERING REGISTER 0 (A).  I DON'T
;KNOW IF ALL THESE CALLS DO, BUT WE'LL ASSUME THAT THEY DO.

TENSW=EMT!145	;UPDATE LOCATION DTESWR FROM THE SWITCHES

EXAM=EMT!103	;EXAMINE PDP10 MEMORY
 ;BEFORE CALL, REGISTER A HAS ADDRESS OF 3 BYTES CONTAINING PDP10 ADDRESS (LOW BITS FIRST)
 ;AFTER CALL, REGISTER A HAS ADDRESS OF 3 WORDS CONTAINING CONTENTS (LOW BITS FIRST)

EXAMT=EMT!104	;EXAMINE PDP10 MEMORY
 ;.WORD PDP10-ADDRESS
 ;.WORD ADDRESS OF 3-WORD DATA BLOCK

DPOS=EMT!105	;DEPOSIT PDP10 MEMORY
 ;BEFORE CALL, REGISTER A HAS ADDRESS OF 3 WORDS CONTAINING CONTENTS
 ;AND REGISTER B HAS ADDRESS OF 3 BYTES CONTAINING ADDRESS

DPOST=EMT!106	;DEPOSIT PDP10 MEMORY
 ;.WORD PDP10-ADDRESS
 ;.WORD ADDRESS OF 3-WORD DATA BLOCK

D10MON=EMT!111	;DEPOSIT PDP10 MEMORY, -1
 ;.WORD PDP10-ADDRESS

$PMSG=EMT!25	;PRINT MESSAGE ON TTY
 ;.WORD ADDRESS OF ASCIZ MESSAGE

$CNTLC=100004	;JUMP HERE TO "CONTROL C" BACK TO KLDCP

;WHEN KLDCP IS IDLE, AND IN "ITS MODE", IT DOES JSR PC,3000
;WHICH CALLS IOELEVEN'S MAIN PROGRAM.  RETURN WITH "C" SET
;TO READ AND EXECUTE ONE KLDCP COMMAND LINE.  RETURN WITH "C"
;CLEAR TO PRINT KL10 HALTED OR CLOCK ERROR STOP MESSAGE.
;LOCATIONS 3004, 3006 MUST CONTAIN .RAD50/IOELEV/
;IOELEV WILL RUN ON KLDCP'S STACK.
;.IFNZ DTE20P
;INFORMATION ABOUT THE DTE20.
;EXCEPT FOR BYTE TRANSFER, WE USE THE TIME-TESTED SUBROUTINES PROVIDED BY KLDCP.

;THE INTERRUPT VECTOR IS AT 774, BUT WE CAN'T USE IT BECAUSE WOULD HAVE
;TO COORDINATE THINGS WITH KLDCP, WHICH IS OBVIOUSLY IMPOSSIBLE.

DLYCNT=174400	;2.6-2.7 UNIBUS ADDRESS EXTENSION FOR BYTE TRANSFER DMA
		;1.1-2.5 14-BIT 2'S COMPLEMENT OF NUMBER OF HALF-MICROSECONDS
		;	 TO DELAY BETWEEN PI0 INTERRUPTS IN BYTE TRANSFER

TO10AD=174420	;ADDRESS (WORD OR BYTE) OF TO-10 BYTE TRANSFER DATA

TO10BC=174414	;1.1-2.3 NEGATIVE BYTE COUNT, 2.7 LAST XFER
		;NORMALLY SET BY 10 WITH DATAO DTE,
		;TO10 XFER STARTS WHEN BOTH TO10AD AND TO10BC HAVE BEEN LOADED

TO11AD=174422	;ADDRESS (WORD OR BYTE) OF TO-11 BYTE TRANSFER DATA

TO11BC=174416	;1.1-2.3 NEGATIVE BYTE COUNT FOR TO-11 BYTE TRANSFER
		;2.5=1 => TO-11 TRANSFER IS 8-BIT BYTES, =0 => 16-BIT WORDS
		;2.6=1 => "ASCIZ" MODE (WHICH WE DON'T USE, OF COURSE)
		;2.7=1 => LAST XFER, UPON COMPLETION INTERRUPT BOTH 10 AND 11
		;   =0 => ONLY INTERRUPT 11.  11 CAN CHANGE TO11AD, TO11BC, CONTINUE.
		;TO11 XFER STARTS WHEN BOTH TO11AD AND TO11BC HAVE BEEN LOADED
		;THE TRANSFER HAPPENS USING DMA (NPR) IN 11, PI LEVEL 0 IN 10.

STATUS=174434	;DTE20 STATUS REGISTER
  ;READS:
 %STDNI==100000	;2.7 TO10 XFER DONE WITHOUT ERROR
 %STERI==20000	;2.5 TO10 XFER ABORTED BY ERROR
		;2.4 DATA OUT OF DTE RAM IS ALL ZERO (MAINT)
 %STINV==4000	;2.3 PDP10 IS INTERRUPTING PDP11
		;2.2 DEPOST OR EXAMINE WORD ONE (MAINT)
 		;2.1 PDP11 MEMORY PARITY ERROR IN TO10 XFER
		;1.9 PDP11 IS INTERRUPTING PDP10
 %STDNO==200	;1.8 TO11 XFER DONE WITHOUT ERROR
		;1.7 E BUFFER SELECT (MAINT)
 		;1.6 TO11 XFER STOPPED DUE TO ZERO BYTE (IN ASCIZ MODE)
		;1.5 TO11 XFER OR PDP10 EXAMINE ENCOUNTERED EBUS PARITY ERROR
		;1.4 1 => RESTRICTED MODE
		;1.3 0 => EXAMINE/DEPOSIT IN PROGRESS, 1 => DONE
 %STERO==2	;1.2 TO11 XFER ABORTED BY ERROR
		;1.1 1 => DTE ENABLED TO INTERRUPT PDP11
  ;WRITES:
 %STCLI==51000	;2.6+2.4+2.1 CLEAR TO10 XFER DONE AND ERROR FLAGS
 %STUNV==2000	;2.2 CLEAR PDP10 INTERRUPTING PDP11
 %STINX==400	;1.9 SET PDP11 INTERRUPTING PDP10
 %STCLO==121	;1.7+1.5+1.1 CLEAR TO11 XFER DONE AND ERROR FLAGS
		;1.6 ENABLE INTERRUPTS
		;1.4 DISABLE INTERRUPTS

DIAG1=174430	;DIAGNOSTIC WORD 1, INCLUDES FLAGS
 %D1ERR==4000	;2.3 KL10 CLOCK ERROR STOP
 %D1RUN==2000	;2.2 KL10 RUN INDICATOR (1 IF 11 WANTS 10 TO RUN)
 %D1HLT==1000	;2.1 KL10 HALT INDICATOR (1 IF 10 DOES A JRST 4)

DIAG3=174436	;DIAGNOSTIC WORD 3, INCLUDES FLAGS
 %D3BYT==1	;1.1 WRITING 0 SETS TO10 XFER IN WORD MODE, 1 BYTE MODE
		;THERE'S NOTHING ELSE OF THE SLIGHTEST USE IN THIS REGISTER,
		;SO IT'S OK TO WRITE IT AT ANY TIME.
.ENDC ;DTE20P

	.SBTTL LOW CORE

.IFZ DTE20P		;IF USING DTE20, THESE ARE SET UP BY KLDCP
.=4
	TRAP4
	340
	TRAP10
	340
;	TRAP14		;SET UP BY 11DDT
;	340
.=20
	TRAP10	;IOT
	340
	PWRFAL
	340
	TRAP10	;EMT
	340
	TRAP10	;TRAP
	340
.ENDC ;DTE20P

.IFNZ MDMP
.=300
	MDMBRK	;DM11-BB
	240	;INTERRUPTS ON BR4 BUT WE MASK TO BR5 ANYWAY
.ENDC ;MDMP
.=60
	DL1IBK	;FIRST DL11 LINE IS PDP11'S CONSOLE TTY, DIFFERENT ADDRESS
	240	;AGAIN INTERRUPTS ON BR4 BUT MASK TO BR5 SO CAN USE DH11 ROUTINES W/O FEAR
	DL1OBK
	240
.=310	
.REPT NDLS-1	;DL11S AFTER THE FIRST ARE IN FLOATING VECTORS
CONC DL,\.RPCNT+2,IBK
	240
CONC DL,\.RPCNT+2,OBK
	240
.ENDR

.=DHIBAS	;DON'T RELY ON RANDOM FLOATING VECTOR TO
		;COME OUT RIGHT, E.G. IF THERE IS A DL11
		;THERE WHICH WE AREN'T USING.
.REPT NDHS		;DH11S ARE IN FLOATING VECTOR AFTER DL11[E]S
CONC DH,\.RPCNT+1,IBK	;DH11 #n RECEIVE
	240
CONC DH,\.RPCNT+1,OBK	;DH11 #n TRANSMIT & ERROR
	240
.ENDR ;NDHS
.=100
	CLKBRK	;KW11-L 60-CYCLE CLOCK
	300	;ON BR6

.IFNZ GOULDP
.=174
	GLPBRK
	300	;BR5 BUT NEED TO LOCK OUT CLOCK SO MASK 6
.ENDC ;GOULDP

.IFG NMPTYS
.=56
MPXENB:	-1	;NONZERO TO ENABLE MULTISCHLUNKER
.ENDC

.IFZ DTE20P	;IF DTE20, KLDCP SUPPLIES THE STACK
.=1000
STKBAS::
	JMP INIT		;START AT 1000 IS CONVENTIONAL
.IFF ;DTE20P
.=3000		;ENTRY VECTOR
	JMP @#INIT
SADR=.-2		;ARG OF THE JMP@# IS CHANGED AFTER INITIALIZATION
	.RAD50 /IOELEV/
.ENDC ;DTE20P

	.SBTTL CONFIGURATION

; TABLES INDEXED BY H (PER HARDWARE UNIT)

.MACRO DHTE AD		;DH11 REGISTER ADDRESS GENERATOR
.REPT NDHS
 <AD>+<20*.RPCNT>
.ENDR
.ENDM

.MACRO DLTE AD		;DL11 REGISTER ADDRESS GENERATOR, FIRST IS WIERD
	177560+<<AD>&7>
.REPT NDLS-1
	<AD>+<10*.RPCNT>
.ENDR
.ENDM

DHSCR:	DHTE 160020	;SYSTEM CONTROL REGISTER
			;1.1-1.4 LINE NUMBER
			;1.5-1.6 MEMORY ADDRESS EXTENSION
 DHRENB==100		;1.7 RECEIVER INTERRUPT ENABLE
			;1.8 RECEIVER INTERRUPT
			;1.9 CLEAR NXM FLAG
			;2.1 MAINTENANCE MODE
 DHSNXM==2000		;2.2 NXM FLAG (GENERATES XMT INTERRUPT)
			;2.3 MASTER CLEAR
 DHSENB==10000		;2.4 STORAGE SILO FULL INTERRUPT ENABLE
 DHTENB==20000		;2.5 TRANSMITTER & NXM INTERRUPT ENABLE
			;2.6 STOARGE FULL INTERRUPT
 DHTDON==100000		;2.7 TRANSMITTER DONE INTERRUPT

DLKS==DHSCR
	DLTE 175610	;KEYBOARD STATUS REGISTER
			;1.1 PAPER TAPE READER ENABLE (WO)
			;1.2 DATA TERMINAL READY (RW)
			;1.3 REQUEST TO SEND (RW)
			;1.4 SECONDARY TRANSMIT DATA [OR MAKE BUSY] (RW)
			;1.5 UNUSED
			;1.6 DATASET INTERRUPT ENABLE (RW)
			;1.7 RECEIVE INTERRUPT ENABLE (RW)
			;1.8 RECEIVE DATA READY (RO)
			;1.9 UNUSED
			;2.1 UNUSED
			;2.2 SECONDARY RECEIVE DATA (RO)
			;2.3 RECEIVE ACTIVE (RO)
			;2.4 CARRIER DETECT (RO)
			;2.5 CLEAR TO SEND (RO)
			;2.6 RING INDICATOR (RO)
			;2.7 DATASET STATUS CHANGE (RO)

DHNRC:	DHTE 160022	;NEXT RECEIVED CHARACTER
			;1.1-1.8 THE CHARACTER
			;1.9-2.3 LINE NUMBER
 %DXPAR==10000		;2.4 CHAR HAS WRONG PARITY
 %DXBRK==20000		;2.5 FRAMING ERROR (BREAK)
 %DXOVR==40000		;2.6 OVERRUN, PREVIOUS CHARS LOST
			;2.7 1 => THIS WORD VALID
DLKB==DHNRC
	DLTE 175612	;KEYBOARD INPUT REGISTER
			;1.1-1.8 RECEIVED DATA
			;2.4 PARITY ERROR (RO)
			;2.5 FRAMING ERROR (RO)
			;2.6 OVERRUN (RO)
			;2.7 OR OF ERROR BITS (RO)

DHLPR:	DHTE 160024	;LINE PARAMETER REGISTER
			;1.1-1.2 CHARACTER LENGTH 0=5, 1=6, 2=7, 3=8 (PARITY BIT EXTRA)
			;1.3 1 => EXTRA STOP BIT
			;1.5 ENABLE PARITY
			;1.6 0 -> EVEN PARITY, 1 => ODD
			;1.7-2.1 RECEIVER SPEED
			; 0 OFF, 1 50, 2 75, 3 110, 4 134.5, 5 150, 6 200, 7 300
			; 10 600, 11 1200, 12 1800, 13 2400, 14 4800, 15 9600, 16 A, 17 B
			;2.2-2.5 TRANSMITTER SPEED, SAME CODES AS RECEIVER
			;2.6 HALF DUPLEX
			;2.7 ECHOPLEX

DHCA:	DHTE 160026	;CURRENT ADDRESS
DLCA==DHCA
	.IREPT NDLS,0

DHBC:	DHTE 160030	;BYTE COUNT (MINUS)
DLBC==DHBC
	.IREPT NDLS,0	;POSITIVE FOR DLS

DHBAR:	DHTE 160032	;BUFFER ACTIVE REGISTER
			;BIT = 1 IF XMT ACTIVE ON CORRESP LINE, NUMBERED RIGHT TO LEFT
DLPS==DHBAR
	DLTE 175614	;PRINTER STATUS
			;1.1 SEND BREAK (RW)
			;1.3 LOOP BACK (RW)
			;1.6 INTERRUPT ENABLE (RW)
			;1.7 TRANSMITTER READY (RO)

DHBCR:	DHTE 160034	;BREAK CONTROL REGISTER
			;BIT = 1 => SEND BREAK ON CORRESP LINE, NUMBERED RIGHT TO LEFT
DLPB==DHBCR
	DLTE 175616	;PRINTER BUFFER
			;1.1-1.8 DATA TO TRANSMIT

DHSSR:	DHTE 160036	;SILO STATUS REGISTER
			;1.1-1.6 SILO ALARM LEVEL
			;1.7-1.8 READ EXTENDED ADDRESS (R.O.)
			;1.9-2.5 SILO FILL LEVEL (R.O.)
			;2.7 MAINTENANCE PATTERN (W.O.)

DHOAC:	.IREPT NDHS,0	;BIT ON IF SOFTWARE THINKS LINE'S TRANSMITTER IS ACTIVE
DLOAC==DHOAC
	.IREPT NDLS,0	;NON-ZERO IF LINE'S TRANSMITTER IS ACTIVE

DHTYNO:	.IREPT NDHS, NFDHTY+<32.*.RPCNT>	;TTY INDEX OF FIRST LINE ON THIS DH11
DLTYNO==DHTYNO
.IIF NZ CTYP,0		;TTY INDEX OF LINE ON THIS DL11
.IREPT NDLS-CTYP,NFDLTY+<2*.RPCNT>

STROUT:	.IREPT NDHS, STRDH	;OUTPUT-START ROUTINES
	.IREPT NDLS, STRDL
.IIF NZ NMPTYS, STRMPK

	.BLKB NFTTY	;AVOID LABEL OVERLAPPAGE

;TABLES INDEXED BY I (PER LINE)

T HDWR:			;HARDWARE UNIT INDEX, GOES IN H
.IIF NZ CTYP, NFDLHX
	.REPT NDHS
	 ZZ==.RPCNT*2
	 .REPT 16.
	  ZZ		;16 LINES ON EACH DH-11
	 .ENDR
	.ENDR
	.=.-<2*NDHUN>
.IREPT NDLS-CTYP,NFDLHX+<2*.RPCNT>+<2*CTYP>
.IREPT NMPTYS,	MPKHWR		;MULTIPLEXOR-KLUDGE TTYS

T DHLSEL:		;DH11 LINE SELECT WORDS
.IIF NZ CTYP,	0		;NONE FOR CTY
	.REPT NDHS
	 .REPT 16.
	  DHTENB+DHRENB+.RPCNT
	 .ENDR
	.ENDR

T DHLBIT:		;BIT CORRESPONDING TO THIS LINE IN DHBAR, ETC.
.IIF NZ CTYP,	0		;NONE FOR CTY
	.REPT NDHS
	 .REPT 16.
	  1←.RPCNT
	 .ENDR
	.ENDR

T BUFPNT:		;BUFFER POINTERS
	.IREPT NCT, BUFFRS+<.RPCNT*MAXBSZ>

T BUFSIZ:		;BUFFER SIZES (I.E. AMOUNT TO USE AT CURRENT SPEED)
	.REPT NCT
	 0		;SET DURING INITIALIZATION
	.ENDR

T NRMIPC:		;NORMAL INPUT CHARACTER PROCESSING ROUTINES
.IIF NZ CTYP, RCV	;CTY NORMAL INPUT
	.REPT 16.*NDHS
	 DHNRMI		;DH11 TTY NORMAL INPUT
	.ENDR
	.=.-<2*NDHUN>
.IREPT NDLS-CTYP,RCV	;DL11 NORMAL INPUT
.IREPT NMPTYS,	RCV	;NORMAL INPUT FOR TTYS ON MULTIPLEXOR-KLUDGE
.IIF NE .-NRMIPC-NLTTY, .ERROR BARF AT NRMIPC
.IFNZ NMPTYS
	.=NRMIPC+MPXIDX
	MPXINP		;INPUT FROM THE MULTIPLEXED LINE IS SPECIAL
	.=NRMIPC+NLTTY
.ENDC

T TTYIPC:		;CURRENT INPUT CHAR PROCESSING ROUTINES
	.BLKW NCT	;SET UP AT INIT TIME
.IIF NE .-TTYIPC-NLTTY, .ERROR BARF AT TTYIPC

T AUTOSP:		;IF NON-ZERO, LINE GOES INTO AUTOSPEED WHEN DIALED UP
	.REPT NCT	;IF MINUS ALSO WHEN BREAK SEEN
	 ZZ===.
	 ASPIRP ↑\
	  .IIF EQ .RPCNT+<NFTTY/2>-N,+1	;THIS LINE AUTOSPEED ON DIALUP
	  .IIF EQ .RPCNT+<NFTTY/2>+N,-1	;ALSO ON BREAK
	  \
	 .IIF EQ .-ZZ, 0	;THIS LINE NOT AUTOSPEED
	.ENDR
.IIF NE .-AUTOSP-NLTTY, .ERROR BARF AT AUTOSP

MCONDX MC
M2LMAP:			;MAP FROM DM11-BB CHANNEL NUMBERS TO TTY INDICES
	2*1		;0 T01
	0		;1 NONE
	0		;2 NONE
	2*4		;3 T04
	2*5		;4 T05
	2*6		;5 T06
	2*7		;6 T07
	0		;7 NONE
	0		;10 NONE
	0		;11 NONE
	0		;12 NONE
	0		;13 NONE
	0		;14 NONE
	0		;15 NONE
	0		;16 NONE
	0		;17 NONE
.IIF NE .-M2LMAP-40, .ERROR BARF AT M2LMAP
.ENDC ;MC

T DIALED:		;0 IF LINE NOT DIALED UP (OR NO MODEM CONTROL ON THIS LINE)
	.REPT NCT	;+ IF DIALED UP (CLEAR TO SEND IS ON)
	 0		;- IF CLEAR TO SEND DROPPED, INC EACH TICK, REACHES 0 => HUNG UP
	.ENDR

T TTYHNG:		;DIALUP/HANGUP STATUS WAITING TO BE SENT TO 10 (0 IF NONE)
	.REPT NCT
	0
	.ENDR

T TYPING:		;NOT 0 IF LINE IS TYPING OUT FOR 10
	.REPT NCT	; WHICH MEANS -10 SHOULD BE INFORMED WHEN TYPEOUT IS FINISHED
	 0
	.ENDR

;MISC VARIABLES

DLXOFF:	-1		;NON-ZERO IF DL10 PORT TURNED OFF BY 10
NO.ITS:	-1		;NON-ZERO IF HAVEN'T ESTABLISHED COMMUNICATION WITH ITS YET
VERSN:	.BYTE NFTTY/2,NCT	;I/O VERSION NUMBER
MDMINI:	0		;NON-ZERO => MODEM SCANNER JUST TURNED ON, GETTING INITIAL STS
WAKE:	0		;CLOCK INTERRUPT WAKE UP MAIN PROGRAM FLAG
HNGSIG:	0		;NUMBER OF NON-ZERO TTYHNG WORDS
.IFNZ DTE20P
CLKENB:	0		;KL10 WANTS 11 TO RELAY CLOCK INTERRUPTS
KLDCPF:	0		;NON-ZERO => USER WANTS TO GIVE A COMMAND TO KLDCP
DDTMOD:	0		;NON-ZERO => DDT MODE TTY INPUT
DDTCHR:	-1		;NON-NEGATIVE => CHAR TYPED FOR DDT
CURSWR:	52525		;LAST SWITCHES SENT TO -10
OUTCMD:	0		;0 IF OUTPUT TRANSFER IDLE
			;ELSE CURRENT COMMAND / 400
OUTSVI:	-1		;LINE# OF CURRENT OUTPUT TRANSFER
OUTSVC:	-1		;#BYTES OF CURRENT OUTPUT TRANSFER
INPCMD:	0		;0 IF INPUT TRANSFER IDLE
			;ELSE CURRENT COMMAND / 400
INPSVI:	-1		;LINE# OF CURRENT INPUT TRANSFER
INPSVC:	-1		;#BYTES OF CURRENT INPUT TRANSFER
.ENDC ;DTE20P
.IFNZ NMPTYS
MPXOAC:	0		;0 IDLE, -1 SENDING HEADER, 1 SENDING DATA
MPXOLN:	0		;2 x MPXK# OUTPUTTING FOR
MPXSEL:	NFMPTY		;TTY INDEX SELECTED FOR MPX INPUT
MPXPNT:	.IREPT NMPTYS,0	;POINTER TO CRUFT TO SEND TO EACH MPXED LINE
MPXNBT:	.IREPT NMPTYS,0	;# BYTES TO SEND, 0 IF IDLE
MPXHED:	.BYTE 0,0	;MPX OUTPUT HEADER: 200+MPXK#, BYTE COUNT
.ENDC ;NMPTYS

;PATCH AREA

PAT: PATCH: .BLKW 200

	.SBTTL RING BUFFERS

.MACRO RING SIZE
	99$		;IN-POINTER
	99$		;OUT-POINTER
	0		;NUMBER OF WORDS IN RING
	<SIZE>		;MAX NUMBER ALLOWED
	<2*<SIZE>>+99$	;MAX ADDRESS ALLOWED
	99$		;MIN ADDRESS ALLOWED
99$:	.BLKW <SIZE>	;BUFFER
.ENDM

RINGIN==0
RINGOT==2
RINGCT==4
RINGSZ==6
RINGTP==10
RINGBT==12
RINGBF==14

; DEFINE THE RING BUFFERS

TYORNG:	RING NCT	;OUTPUT-DONE RING, CONTENTS = LINE NUMBER PDP10 STYLE

TYIRSZ==NCT*20		;8 CHARS PER TTY (2 WORDS PER CHAR)
TYIRNG:	RING TYIRSZ	;TTY INPUT RING, FIRST WORD IS CHARACTER, SECOND LINE NUMBER



;MOV #RING,B
;MOV WORD,A
;CALL PUT

PUT:	CMP RINGCT(B),RINGSZ(B)
	BLT 1$
	 BPT		;BLOATED
1$:	PUSH C
	MOV RINGIN(B),C
	MOV A,(C)+
	CMP C,RINGTP(B)
	BLO 2$
	 MOV RINGBT(B),C
2$:	MOV C,RINGIN(B)
	POP C
	INC RINGCT(B)
	RET

;MOV #RING,B
;CALL GET
;WORD RETURNED IN A
; IT IS AN ERROR TO CALL THIS IF RING IS EMPTY

GET:	TST RINGCT(B)
	BGT 1$
	 BPT		;EMPTY
1$:	PUSH C
	MOV RINGOT(B),C
	MOV (C)+,A
	CMP C,RINGTP(B)
	BLO 2$
	 MOV RINGBT(B),C
2$:	MOV C,RINGOT(B)
	POP C
	DEC RINGCT(B)
	RET
.IFNZ DTE20P
	.SBTTL DTE20 SUBROUTINES

;THE DTE20 MUST NOT BE HACKED AT INTERRUPT LEVEL, BECAUSE KLDCP USES IT TOO.
;THE FOLLOWING THREE LOCATIONS ARE ARGS TO/FROM THE FOLLOWING TWO SUBROUTINES.

LH:	0	;LOW 16 BITS OF LEFT HALF
RH:	0	;LOW 16 BITS OF RIGHT HALF
SNB:	0	;SIGN BIT (0 IF +, NON-0 IF -)

;JSR B,HWEXAM
; .WORD ADDR
;EXAMINE PDP10 LOC, SPLIT INTO HALFWORDS, SET LH, RH, SNB
;RETURNS WITH "Z" SET IF LOCATION HAS POSITIVE SIGN, "Z" CLEAR IF MINUS SIGN

HWEXAM:	PUSH <A,C>	;SAVE REGS
	PUSH <#0,(B)+>	;PUT PDP10 ADDRESS ONTO PDL
	MOV SP,A	;SET UP POINTER TO ADDRESS
	EXAM		;EXAMINE LOCATION, SET A TO POINT TO 3-WORD RESULT BUFFER
	 BCS UHUNG	;BRANCH IF UCODE HUNG
	MOV (A)+,RH	;LOW 16 BITS => RH
	MOV (A)+,C	;PICK UP MIDDLE 16 BITS
	MOV (A)+,A	;PICK UP HIGH 4 BITS
	ROR A		;LSHC <A,C>,-2 TO GET PDP10 LH INTO C
	ROR C
	ROR A
	ROR C	
	MOV C,LH
	BIC #177775,A	;LEAVE SIGN BIT IN 1.2 OF A
	MOV A,SNB
	ADD #4,SP	;POP ADDRESS OFF PDL
	POP <C,A>	;RESTORE REGS
	TST SNB
	RTS B		;RETURN SKIPPING IN-LINE PARAMETER

;JSR B,HWDEP
; .WORD ADDR
;ASSEMBLE LH, RH, SNB INTO PDP10 AND DEPOSIT IN ADDR

HWDEP:	PUSH <A,B,C>
	MOV LH,C
	CLR A
	TST SNB
	BEQ 1$
	MOV #2,A
1$:	ASL C
	ROL A
	ASL C
	ROL A
	PUSH <A,C,RH>	;PUSH HIGH, MIDDLE, AND LOW BITS
	MOV SP,A	;POINTER TO DATA
	PUSH <#0,(B)>	;PUSH HIGH AND LOW ADDRESS
	MOV SP,B	;POINTER TO ADDRESS
	DPOS		;DO THE DEPOSIT
	 BCS UHUNG	;BRANCH IF UCODE HUNG
	ADD #10.,SP	;POP ADDRESS AND DATA OFF PDL
	POP <C,B,A>
	TST (B)+	;SKIP TRAILING PARAMETER
	RTS B

UHUNG:	$PMSG
	 .WORD 1$
	JMP $CNTLC

1$:	.ASCIZ/?MICROCODE HUNG/

.ENDC ;DTE20P
.IFNZ DL10P
	.SBTTL MAIN LOOP FOR DL10

MAIN:	BIT #DLXPRT,DLXCSR	;PORT TO 10 ENABLED?
	BNE 1$			;YES
	SETOM NO.ITS		;NO, FLAG THERE IS NO ITS
	SETOM DLXOFF		;AND THAT WE THINK DL10 PORT IS OFF
	BR MAIN			;AND WAIT FOR IT TO TURN ON

1$:	TST DLXOFF		;DID DL10 JUST TURN ON?
	BEQ 4$			;NO, IT WAS ON BEFORE
	CLR DLXOFF		;YES, SO REMEMBER THAT,
	CMP VERS,VERSN		;AND COMPARE -10 AND -11 VERSIONS
	BEQ 2$
	 BPT			;-10 AND -11 PROGRAMS NOT SAME CONFIG
2$:

;WAIT FOR -10 TO REQUEST SERVICE, OR CLOCK TO TICK

4$:	BIT #DLX11I,DLXCSR	;10 REQUESTING SERVICE?
	BEQ 10$
	BIS #DLXZ11,DLXCSR	;YES, CLEAR FLAG
	BR CHKOST		;AND GO CHECK FOR THINGS TO DO

10$:	TST WAKE		;NO, CHECK ANYWAY IF 60 CYCLE CLOCK HAS TICKED
	BEQ MAIN		;NEITHER, JUST WAIT
	CLR WAKE		;CLOCK HAS TICKED, CLEAR FLAG
	INC DLXUP		;AND INCREMENT COUNTER 10 IS SUPPOSED
	BEQ 11$			; TO SETOM EVERY 1/2 SEC
	CMP DLXUP,#100.		;IF IT MISSES THREE SLOW CLOCK BREAKS IN A ROW,
	BLE 12$
	SETOM NO.ITS		; CONSIDER IT DOWN.
	MOV #100.,DLXUP		;DON'T LET COUNTER OVERFLOW
	BR 12$

11$:	CLR NO.ITS		;-10 HAS SETOMED COUNTER, IT'S UP
12$:	;FALL INTO CHKOST

; CHECK FOR OUTPUT-START FROM -10

CHKOST:	MOV TTYST,A		;LINE# TO START OUTPUT
	BEQ CHKOUT		;NONE.
	CLR TTYST		;TELL -10 IT'S BEEN PICKED UP
	MOV #TYORNG,B	
	MASK 5			;DON'T INTERFERE WITH P.I. LEVEL
	CALL PUT		;PUT IN RING, LATER WILL SEND IT BACK TO 10
	UNMASK

; CHECK FOR TTY OUTPUT SENT BY -10

CHKOUT:	MOV TYOLIN,I		;OUTPUT TO BE DONE?
	BEQ CHKIN		;NO.
	MOV TYOCNT,C		;YES, GET NUMBER OF CHARS
	CALL TYOSER		;CALL OUTPUT HANDLER
	CLR TYOLIN		;TELL 10 WE'VE GOBBLED THE OUTPUT
	BIS #DLX10I,DLXCSR	;GIVE TRANSFER-COMPLETE INTERRUPT

; CHECK FOR TTY INPUT TO BE SENT TO -10

CHKIN:	TST TYIRNG+RINGCT
	BEQ CHKDON		;NO STATUS TO BE STORED
	TST TYILIN
	BNE CHKDON		;PREVIOUS STATUS NOT PICKED UP
	MOV #TYIRNG,B
	CALL GET
	MOV A,TYICHR		;GIVE INPUT CHARACTER TO 10
	CALL GET
	MOV A,TYILIN		;GIVE LINE NUMBER TO 10
	BIS #DLX10I,DLXCSR	;SEND INTERRUPT TO 10

; CHECK FOR OUTPUT-DONE TO BE SENT TO -10

CHKDON:	TST TYORNG+RINGCT
	BEQ CHKHNG		;NO STATUS TO BE STORED
	TST TYOSTS
	BNE CHKHNG		;PREVIOUS STATUS NOT PICKED UP
	MOV #TYORNG,B
	CALL GET
	MOV A,I
	ASL I
	MOV BUFSIZ(I),TYOBSZ	;TELL -10 HOW MANY CHARS TO GIVE
	MOV A,TYOSTS		;GIVE OUTPUT DONE TO 10
	BIS #DLX10I,DLXCSR	;WITH INTERRUPT

; CHECK FOR HANGUPS TO BE SENT TO -10

CHKHNG:	TST HNGSIG		;ANY HANGUPS TO BE REPORTED?
	BEQ CHKLPR		;NO
	TST HNGLIN
	BNE CHKLPR		;PREVIOUS STATUS NOT PICKED UP
	MOV #LASTTY,I		;SCAN OVER ALL LINES
1$:	MASK 5
	MOV TTYHNG(I),A		;GET HANG-UP STATUS
	BNE 2$			;BRANCH IF FOUND SOMETHING TO REPORT
	UNMASK
	TST -(I)
	CMP I,#NFTTY
	BHIS 1$
	BPT			;HNGSIG OUT OF PHASE WITH TTYHNG

2$:	CLR TTYHNG(I)		;GOT STATUS, CLEAR IT
	DEC HNGSIG		;DECREASE COUNT OF FROBS WAITING TO BE SIGNALLED
	UNMASK			;NOW IT'S OK TO INTERRUPT AND SET TTYHNG
	MOV A,HNGLIN		;GIVE LINE NUMBER AND OTHER DATA TO 10
	BIS #DLX10I,DLXCSR	;WITH INTERRUPT

; CHECK FOR REQUEST FROM -10 TO SET LINE PARAMETERS

CHKLPR:	MOV LPRLIN,I		;LINE PARAMETERS TO BE SET?
	BEQ CHKEXD		;NO.
	ASL I			;YES, GET LINE INDEX
	MOV LPRLPR,A		;AND DH11 PARAMETER REGISTER VALUE
	MOV LPRBSZ,B		;AND BUFFER SIZE
	CALL SPARAM		;CALL PARAMETER SETTER
	CLR LPRLIN		;TELL 10 IT IS DONE

; CHECK FOR EXAMINE/DEPOSIT REQUEST FROM -10

CHKEXD:	TST EXDSTS		;EXAMINE/DEPOSIT?
	BEQ CHKGLD		;NO.
	MOV EXDADR,A		;GET ADDRESS
	CMP EXDSTS,#2
	BNE 21$
	MOV EXDDAT,(A)		;DEPOSIT
21$:	MOV (A),EXDDAT		;EXAMINE
	CLR EXDSTS		;IT IS DONE

;CHECK FOR GOULD LPT OUTPUT

CHKGLD:
.IF EQ GOULDP
	CLR GLPCTR		;IF NO GOULD, FLUSH OUTPUT FOR IT
	SETOM GLPTER		;AND SAY "NOT READY"
.IFF
	TST GLPCTR		;ANY BYTES IN BUFFER?
	BEQ 1$
	CALL GLPTYO		;YES, OUTPUT THEM
1$:	MOV GLPERR,GLPTER	;COPY ERROR STATUS FROM P.I. LEVEL TO -10
.ENDC				;DONE HERE SO NO USE OF DL10 AT P.I. LEVEL
;	BR MAINX

MAINX:	JMP MAIN		;THAT'S IT
MAINE::
.ENDC ;DL10P
.IFNZ DTE20P
	.SBTTL MAIN LOOP FOR DTE20

MAIN:	BIT #%D1RUN,DIAG1	;IS KL10 RUNNING?
	BEQ TENDED		;NO, LOSE!
	BIT #%D1ERR+%D1HLT,DIAG1	;HAS KL10 CLOCK STOPPED FOR HARDWARE ERROR? OR JRST 4
	BNE TENDED		;YES, LOSE!
	TST KLDCPF		;MAYBE USER WANTS TO GIVE A KLDCP COMMAND?
	BNE KLDCPR		;YES, RETURN TO KLDCP
	TSTB @DLKS+NFDLHX	;CTY INPUT?
	BPL 10$			;TEST KBD BEFORE CLK SINCE MIGHT BE MORE THAN
				; 1/60'TH SECOND PER TRIP AROUND THE LOOP.
	MASK 5			;YES, SIMULATE INTERRUPT
	CALL DL1IBK		;CAN'T USE REAL INTS BECAUSE WOULD INTERFERE WITH KLDCP
10$:	TSTB LKS		;60 CYCLE CLOCK TICK?
	BMI CLKSER		;YES
	BIT #%STINV,STATUS	;REQUEST FROM 10?
	BNE TENSER		;YES, SERVICE IT.
	BIT #%STDNI,STATUS	;TO10 XFER COMPLETE?
	BNE INPDON		;YES, SERVICE IT.
	BIT #%STDNO,STATUS	;TO11 XFER COMPLETE?
	BNE OUTDON		;YES, SERVICE IT.
	BIT #%STERI+%STERO,STATUS
	BNE LOSSAG		;BYTE TRANSFER LOST
	BR MAIN			;CLOSE LOOP

;60-CYCLE CLOCK SERVICE

CLKSER:	CLR LKS			;CLEAR CLOCK FLAG
	TST CLKENB		;DOES 10 WANT CLOCK INTERRUPTS?
	BEQ 1$
	D10MON			;YES, GIVE ONE
	    DTECLK		;SET CLOCK FLAG IN LOW CORE
	 BCS UHUNG
	MOV #%STINX,STATUS	;AND SEND INTERRUPT
1$:	CMP SWR,CURSWR		;MAYBE NEED TO UPDATE 10'S SWITCHES
	BEQ 2$
	MOV SWR,CURSWR
	TENSW			;LET KLDCP DO IT
	 BCS UHUNG
2$:	JSR B,HWEXAM		;INCREMENT COUNTER -10 IS SUPPOSED
	    DTECHK		; TO SETOM EVERY HALF-SECOND
	CLR LH
	CLR SNB
	INC RH
	BEQ 3$
	CMP RH,#100.		;IF IT MISSES THREE SLOW CLOCK BREAKS IN A ROW,
	BLE 4$
	SETOM NO.ITS		;THEN IT IS DOWN
	MOV #100.,RH		;DON'T LET COUNTER OVERFLOW
	BR 4$

3$:	CLR NO.ITS		;IT SETOMED COUNTER, IT'S UP.
4$:	JSR B,HWDEP		;PUT COUNTER BACK
	    DTECHK
	MASK 6			;NOW SIMULATE BR6 CLOCK INTERRUPT
	CALL CLKBRK
	BR TENSER		;AND GO SERVICE 10 (IN CASE LOST INTERRUPT)

; HERE IF KL10 HALTS

TENDED:	SETOM NO.ITS
	CLC
	RET			;LET KLDCP PRINT THE MESSAGE

; BYTE TRANSFER ENCOUNTERED HARDWARE LOSSAGE

LOSSAG:	BPT
	BR LOSSAG

; USER WANTS TO GIVE A KLDCP COMMAND

KLDCPR:	CLR KLDCPF
	SEC
	RET

TENSER:	JMP TENSR0

; HERE WHEN TO10 BYTE TRANSFER COMPLETE

INPDON:	MOV #%STCLI,STATUS	;CLEAR FLAGS IN DTE20
	MOV INPCMD,A		;GET COMMAND FOR XFER THAT JUST FINISHED
	BNE 1$
	 BPT			;WOOPS, NO XFER IN PROGRESS
1$:	CLR INPCMD		;NO XFER IN PROGRESS NOW
	MOV INPSVI,I
	MOV INPSVC,C
	CALL @FINAL-2(A)	;CALL APPROPRIATE FINISHER ROUTINE
	BR MAIN

; HERE WHEN TO11 BYTE TRANSFER COMPLETE

OUTDON:	MOV #%STCLO,STATUS	;CLEAR FLAG
	MOV OUTCMD,A		;GET COMMAND FOR XFER THAT JUST FINISHED
	BNE 1$
	 BPT			;WHOOPS, NO XFER IN PROGRESS
1$:	CLR OUTCMD		;NO XFER IN PROGRESS NOW
	MOV OUTSVI,I
	MOV OUTSVC,C
	CALL @FINAL-2(A)	;CALL APPROPRIATE FINISHER ROUTINE
	BR MAINJ

; HERE TO START TO10 BYTE TRANSFER.  HWEXAM OF DTEINP HAS BEEN DONE.

INPSER:	D10MON			;VALUE HAS BEEN PICKED UP, SETOM IT
	    DTEINP
	BIT #1000,LH		;RIGHT GENDER OF COMMAND?
	BEQ OUTSR1		;YES
	BR MAINJ		;(USED TO BE BPT) NO, IGNORE, MAYBE ITS BEING RELOADED

; HERE TO START TO11 BYTE TRANSFER.  HWEXAM OF DTEOUT HAS BEEN DONE.

OUTSER:	D10MON			;VALUE HAS BEEN PICKED UP, SETOM IT
	    DTEOUT
	BIT #1000,LH		;RIGHT GENDER OF COMMAND?
	BNE OUTSR1		;YES
	BR MAINJ		;(USED TO BE BPT) NO, IGNORE, MAYBE ITS BEING RELOADED

OUTSR1:	MOV RH,C		;GET BYTE COUNT
	MOVB LH,I		;GET LINE#
	MOVB LH+1,A		;GET COMMAND TIMES 2
	BEQ MAINJ		;CLEARING CORE?  IGNORE ZERO COMMAND
	BLE OUTSR2
	CMP A,#LBEGIN
	BGT OUTSR2
	CALL @BEGIN-2(A)	;CALL APPROPRIATE BEGIN-XFER ROUTINE
	BIT #2,A
	BNE 1$
	MOV A,INPCMD		;REMEMBER CRUFT FOR XFER IN PROGRESS
	MOV I,INPSVI
	MOV C,INPSVC
	BR MAINJ

1$:	MOV A,OUTCMD		;REMEMBER CRUFT FOR XFER IN PROGRESS
	MOV I,OUTSVI
	MOV C,OUTSVC
MAINJ:	JMP MAIN

OUTSR2:	BR MAINJ		;BAD COMMAND FROM 10 (USED TO BE BPT) JUST IGNORE IT

;TABLE OF ROUTINES TO PROCESS DATA TRANSFER COMMANDS FROM -10

BEGIN:	TYOSER			;%DTTYO
	ETHISR			;%DTETI
	ETHOSR			;%DTETO
LBEGIN==.-BEGIN

;TABLE OF ROUTINES TO FINISH UP DATA TRANSFERS

FINAL:	TYOFIN			;%DTTYO
	ETHIFN			;%DTETI
	ETHOFN			;%DTETO

;CHECK FOR COMMANDS FROM 10, STORE STATUS IN ANY STATUS WORDS
;THAT 10 HAS SET BACK TO -1

TENSR0:	MOV #%STUNV,STATUS	;CLEAR 10 INTERRUPTING 11 FLAG
	JSR B,HWEXAM		;CHECK FOR A NON-TIMESHARING COMMAND
	    DTECMD
	MOV RH,A		;IS THERE ONE?
	BEQ TENSR1		;NO, GO CHECK FOR TIMESHARING STUFF
	CLR LH
	CLR SNB
	CMP A,#377
	BHI 2$
1$:	TSTB TPS		;CHAR TO BE TYPED, WAIT FOR READY
	BPL 1$
	MOVB A,TPB		;TYPE IT OUT
9$:	CLR RH			;CLEAR OUT THE COMMAND
	JSR B,HWDEP
	    DTECMD
	D10MON			;TELL 10 IT'S DONE
	    DTEFLG
	JMP MAIN

2$:	CMP A,#%DTTYI
	BNE 5$
	CLR RH			;SNB,LH,RH NOW HAS ZERO
	SETOM DDTMOD		;KEYBOARD INPUT WANTED
	TST DDTCHR		;TEST IF READY
	BMI 3$			;IF NO INPUT, GIVE ZERO
	MASK 5
	MOV DDTCHR,RH		;GIVE THE CHAR
	COM DDTCHR		;MAKE NEGATIVE
	UNMASK
3$:	JSR B,HWDEP
	    DTEF11
	BR 9$

5$:	CMP A,#%DTCLN
	BNE 6$
	SETOM CLKENB
	BR 9$

6$:	CMP A,#%DTCLF
	BNE 7$
	CLR CLKENB
	BR 9$

7$:	BPT			;SOME COMMAND WE DON'T IMPLEMENT
	BR 9$			;IF CONTINUED, IGNORE IT

;CHECK FOR ITS UP/DOWN

TENSR1:	TST NO.ITS		;IF SYSTEM ISN'T UP,
	BNE MAINJ		;DON'T TRY TO HACK TS STUFF
	INC DLXOFF		;OTHERWISE, FIRST TIME THROUGH HERE
	BNE CHKOST		;WE CHECK THE VERSION
	JSR B,HWEXAM
	    DTEVER
	TST RH			;STORED?
	BNE 1$
	DEC DLXOFF		;NO, DON'T LOOK AT IT
	BR MAINJ		;PROBABLY CORE BEING CLEARED

1$:	CMP RH,VERSN
	BEQ CHKOST
	 BPT			;-10 AND -11 PROGRAMS NOT SAME VERSION

CHKOST:	JSR B,HWEXAM		;CHECK FOR 10 WANTING OUTPUT START
	    DTEOST
	BNE CHKTRN		;BRANCH IF LOCATION DTEOST IS -1
	D10MON			;HAVING PICKED IT UP, SET BACK TO -1
	    DTEOST
	MOV RH,A
	MOV #TYORNG,B
	MASK 5			;DON'T INTERFERE WITH P.I. LEVEL
	CALL PUT
	UNMASK
	CLR DDTMOD		;SYSTEM UP, TURN OFF DDT MODE
	MOV #-1,DDTCHR		;..

CHKTRN:	TST INPCMD
	BNE 1$			;INPUT IN PROGRESS, DON'T START AGAIN
	JSR B,HWEXAM		;CHECK FOR DATA TRANSFER COMMAND
	    DTEINP
	BNE 1$			;DTEINP -1, NO REQUEST
	JMP INPSER

1$:	TST OUTCMD
	BNE CHKLSP		;OUTPUT IN PROGRESS, DON'T START AGAIN
	JSR B,HWEXAM		;CHECK FOR DATA TRANSFER COMMAND
	    DTEOUT
	BNE CHKLSP		;DTEOUT -1, NO REQUEST
	JMP OUTSER

CHKLSP:	JSR B,HWEXAM		;CHECK FOR SET LINE SPEED COMMAND
	    DTELSP
	BNE CHKTYI
	MOV RH,I		;GET LINE#
	ASL I
	CMP I,#NFTTY		;VALIDATE IT
	BLO 1$			;IGNORE IF BAD
	CMP I,#LASTTY
	BHI 1$
	JSR B,HWEXAM		;GET LPR,,BUFFERSIZE
	    DTELPR
	MOV LH,A
	MOV RH,B
	CALL SPARAM		;DO IT
1$:	D10MON			;DONE, SETOM
	    DTELSP

CHKTYI:	TST TYIRNG+RINGCT
	BEQ CHKODN		;NO TTY INPUT WAITING
	JSR B,HWEXAM
	    DTETYI
	BEQ CHKODN		;PREVIOUS CHAR NOT PICKED UP
	MOV #TYIRNG,B
	CALL GET
	MOV A,RH		;CHAR
	CALL GET
	MOV A,LH		;LINE#
	CLR SNB
	JSR B,HWDEP		;GIVE 10 LINE#,,CHAR
	    DTETYI
	MOV #%STINX,STATUS	;INTERRUPT THE 10

CHKODN:	TST TYORNG+RINGCT
	BEQ CHKHNG		;NO OUTPUT DONES WAITING
	JSR B,HWEXAM
	    DTEODN
	BEQ CHKHNG		;PREVIOUS STATUS NOT PICKED UP
	MOV #TYORNG,B
	CALL GET		;GET LINE# WITH OUTPUT DONE
	MOV A,LH
	ASL A
	MOV BUFSIZ(A),RH
	CLR SNB
	JSR B,HWDEP		;GIVE 10 LINE#,,BUFFERSIZE
	    DTEODN
	MOV #%STINX,STATUS	;INTERRUPT THE 10

CHKHNG:	TST HNGSIG
	BEQ MAINX		;NO HANGUPS/DIALINS WAITING
	JSR B,HWEXAM
	    DTEHNG
	BEQ MAINX		;PREVIOUS STATUS NOT PICKED UP
	MOV #LASTTY,I		;SCAN OVER ALL LINES
1$:	MASK 5
	MOV TTYHNG(I),A		;GET HANG-UP STATUS
	BNE 2$			;BRANCH IF FOUND SOMETHING TO REPORT
	UNMASK
	TST -(I)
	CMP I,#NFTTY
	BHIS 1$
	BPT			;HNGSIG OUT OF PHASE WITH TTYHNG

2$:	CLR TTYHNG(I)		;GOT STATUS, CLEAR IT
	DEC HNGSIG		;DECREASE COUNT OF FROBS WAITING TO BE SIGNALLED
	UNMASK			;NOW IT'S OK TO INTERRUPT AND SET TTYHNG
	MOV A,RH		;GIVE LINE NUMBER AND OTHER DATA TO 10
	CLR LH
	CLR SNB
	JSR B,HWDEP
	    DTEHNG
	MOV #%STINX,STATUS	;INTERRUPT THE 10

MAINX:	JMP MAIN
.ENDC ;DTE20P

	.SBTTL OUTPUT HANDLERS

TYOSER:	ASL I				;CONVERT -10 LINE# TO -11 TTY INDEX
	CMP I,#NFTTY
	BLO 11$
	CMP I,#LASTTY
	BLOS 12$
11$:	BPT				;10 GAVE BAD LINE#
12$:	MOV HDWR(I),H			;GET HARDWARE INDEX
	MOV BUFPNT(I),D			;AND ADDRESS OF TYPEOUT BUFFER
	CMP BUFSIZ(I),C			;MAKE SURE THERE IS ROOM IN BUFFER
	BHIS 2$
	 BPT				;THERE ISN'T
2$:	MOV C,B				;MUSTN'T CLOBBER BYTE COUNT IN C
.IFNZ DL10P
	MOV #TYOPNT,A			;GET CRUFT FROM DL10
3$:	MOVB @A,(D)+			;COPY BUFFER
	SOB B,3$
.ENDC ;DL10P
.IFNZ DTE20P
	MOV D,TO11AD			;SET UP BYTE TRANSFER
	NEG B
	BIC #050000,B			;SET LAST, BYTE; CLEAR ASCIZ, 2.4
	MOV B,TO11BC			;START XFER
	RET

TYOFIN:	MOV HDWR(I),H			;COMES BACK WHEN XFER COMPLETE
.ENDC ;DTE20P

;BUFFER HAS BEEN LOADED, START DEVICE

	MASK 5				;DON'T LET DEVICE INTERRUPT
	MOV BUFPNT(I),D
	CALL @STROUT(H)			;CALL DEVICE-DEPENDENT ROUTINE
	SETOM TYPING(I)			;TELL 10 WHEN OUTPUT FINISHES
	UNMASK
	RET

;GIVE MESSAGE.  A -> .WORD LENGTH,MSG.  I HAS LINE NUMBER.

GIVMSG:	PUSH <C,D>
	MOV (A)+,C		;C HAS BYTE COUNT, A HAS ADDRESS
	MOV A,D			;PUT ADDRESS IN D
	MOV HDWR(I),H
	MASK 5
	CALL @STROUT(H)		;START OUTPUT TO LINE
	UNMASK
	POP <D,C>
	RET

ASPACK:	MNAME ↑%
	MSG ↑\
␈␈Connected to MCHN'.\%
DWNMSG:	MSG ↑\
␈␈ITS is down.\
IBOMSG:	MSG ↑\IBO\

;DEVICE-DEPENDENT OUTPUT START ROUTINES  (CALL AT PI LEVEL 5)
;H HDWR IDX, I TTY IDX, D BUFFER POINTER, C NUMBER OF BYTES

STRDH:	BIC DHLBIT(I),@DHBAR(H)		;IF LINE ALREADY TRANSMITTING, STOP IT
					;IT SHOULDN'T OUGHT TO BE...
	MOV DHLSEL(I),@DHSCR(H)		;HARDWARILY SELECT THIS LINE
	MOV D,@DHCA(H)			;SET XMT ADDRESS
	NEG C				;HARDWARE LIKES NEGATIVE BYTE COUNTS
	MOV C,@DHBC(H)			;SET XMT COUNT
	BIS DHLBIT(I),@DHBAR(H)		;START TRANSMISSION HARDWARILY
	BIS DHLBIT(I),DHOAC(H)		;SOFTWARILY ALSO
	RET

STRDL:	MOV D,DLCA(H)
	MOV C,DLBC(H)
	CLR @DLPS(H)
	MOV #300,@DLPS(H)		;CAUSE INTERRUPT
	SETOM DLOAC(H)
CPOPJ:	RET

.IFNZ NMPTYS
STRMPK:	TST MPXENB
	BEQ CPOPJ
	MOV D,MPXPNT-NFMPTY(I)		;QUEUE OUTPUT
	MOV C,MPXNBT-NFMPTY(I)
STRMPX:	PUSH I
	TST MPXOAC			;START THE MPXR
	BNE 10$				;ALREADY BUSY
	CLR I
	MOV #NMPTYS,D
2$:	MOV MPXNBT(I),C			;FIND MPX KLUDGE LINE WANTS TO OUTPUT
	BNE 15$
	TST (I)+
	SOB D,2$
10$:	POP I
	RET

15$:	MOV I,MPXOLN			;SAVE LINE# OUTPUT ON
	ASR I				;SET UP HEADER
	ADD #200,I
	MOVB I,MPXHED
	MOVB C,MPXHED+1
	MOV #-1,MPXOAC			;SEND HEADER
	MOV #MPXIDX,I
	MOV HDWR(I),H
	MOV #MPXHED,D
	MOV #2,C
	CALL @STROUT(H)
	BR 10$
.ENDC ;NMPTYS

.IFNZ GOULDP
.SBTTL GOULD LPT OUTPUT (M.P. LEVEL)
.IIF Z DL10P, .ERROR GOULD LPT ONLY CODED FOR DL10

GLPTYO:	MOV GLPOIP,H		;GET NEXT BUFFER
	CMP GB.STA(H),#%GBMP
	BEQ 2$			;BRANCH IF M.P. ACTIVE
	BLT 1$			;BRANCH IF IDLE BUFFER AVAIL
	RET			;NO FREE BUFFERS

1$:	CALL GLPBGB		;GOBBLE A BUFFER
2$:	MOV GB.PNT(H),D
	MOV GLPCTR,C		;SET UP BYTE COUNTER
	MOV GLPGRF,GLPGF1	;COPY ARG FROM 0 FOR SPEED
	TST GLIMBF		;CHAR SAVED FROM LAST TIME?
	BEQ GLPNCL
	CLR GLIMBF		;YES, PRINT IT
	MOVB GLIMBO,A
	CALL GLPPUT
	MOVB GLIMBO+1,A		;SECOND CHAR?
	BEQ GLPNCL
	CLR GLIMBO
	CALL GLPPUT

;CHARACTER PROCESSING LOOP
;C HAS # CHARS YET TO GO, D HAS WHERE TO PUT THEM, H -> BUFFER
;A WILL HAVE CHAR

GLPNCL:	MOV GLPPTR,A		;GET NEXT CHAR
	TST GLPGF1
	BNE GLPNRM		;GRAPHIC MODE, NO CHARACTER PROCESSING
	CMP A,#177		;ESCAPE?
	BEQ GLPESC
	CMP A,#40		;CONTROL?
	BGE GLPNRM		;NO, NORMAL PRINTING
	CMP A,#14		;CHECK FOR SPECIAL CONTROLS
	BNE 10$
8$:	CLR GLPROW		;START NEW PAGE
	TST GLPCOL		;IN MIDDLE OF LINE?
	BEQ 9$			;NO, OK
	CALL GLPBWW		;OTHERWISE, HAIR
	CLR GLPFIL		;HACK HACK MAKE FF NEXT LINE
	BR GLPNB1

9$:	SETOM GB.FF(H)
	BR GLPNXC

10$:	CMP A,#12
	BNE 12$
	INC GLPROW
	CMP GLPROW,#GLPRMX
	BHIS 8$			;SKIP OVER PERFORATION
	TST GLPCOL
	BNE GLPNBF		;IF NOT A BLANK LINE, FINISH BUFFER
	INC GB.NL(H)
	BR GLPNXC

12$:	CMP A,#11
	BNE 15$
13$:	MOV #40,A		;TAB - SPACE OVER
	CALL GLPPUT
	BIT #7,GLPCOL
	BNE 13$
	BR GLPNXC

15$:	CMP A,#15
	BEQ GLPNXC		;IGNORE CR
	CMP A,#33
	BNE 16$
	MOV #'$,A		;PRINT ALTMODE AS DOLLAR
	BR GLPNRM

16$:	BIS #100,A		;RANDOM CONTROL AS UPARROW, LETTER
	MOVB A,GLIMBO+1
	MOV #'↑,A
	CALL GLPPUT
	MOVB GLIMBO+1,A
	CLR GLIMBO	
GLPNRM:	CALL GLPPUT		;HERE FOR NORMAL CHARACTER
GLPNXC:	DEC C			;HERE TO GOBBLE CHARACTER
	BGT GLPNCL		;BRANCH IF MORE CHARS TO GO
	BR GLPEND		;BUFFER EMPTIED

GLPNBF:	CALL GLPBWW		;HERE TO ADVANCE TO NEXT BUFFER
GLPNB1:	CMP GB.STA(H),#%GBIDL	;NEXT BUFFER AVAIL?
	BNE GLPEN1		;NO, STOP
	CALL GLPBGB		;YES, GOBBLE IT
	BR GLPNXC

GLPESC:	DEC C			;HERE FOR TWO CHAR ESC SEQ
	BEQ GLPEND		;-10 FORGOT 2ND CHAR, FLUSH
	MOV GLPPTR,A		;GET & DECODE 2ND CHAR
	CMP A,#105		;EOF
	BEQ GLPEOF
	BR GLPNXC		;OTHER CHARS ARE IGNORED

GLPEOF:	CLR GLPFIL
	CLR GLPROW
	CALL GLPBWW		;EOF, WRITE LAST BUFFER
GLPEN1:	DEC C			;GOBBLE A CHARACTER
GLPEND:	MOV C,GLPCTR		;HERE WHEN DONE, RELEASE 10'S BUFFER
	CMP GB.STA(H),#%GBMP	;BUFFER ACTIVE AT M.P. LEVEL?
	BNE 1$			;IF NOT, DON'T CLOBBER GB.PNT
	MOV D,GB.PNT(H)		;IF SO, REMEMBER AMT OF STUFF IN CURRENT BUFFER
1$:	RET			;RETURN TO MAIN LOOP

;OUTPUT PRINTING CHAR IN A

GLPPUT:	CMP D,GLPLIM		;LINE OVERFLOW?
	BLO 5$			;NO
	CALL GLPBWW		;YES, DONE WITH THIS BUFFER
	INC GLPROW		;OUGHT TO CHECK FOR PERFORATION, BUT...
	CMP GB.STA(H),#%GBIDL	;MORE BUFFERS?
	BNE 6$			;NO
	CALL GLPBGB
5$:	MOVB A,(D)+		;DROP CHAR IN BUFFER
	INC GLPCOL		;AND ADVANCE COLUMN
	RET

6$:	MOVB A,GLIMBO		;NO BUFFERS, SAVE CHAR BEING PRINTED
	SETOM GLIMBF		;SET FLAG SO WILL BE PRINTED NEXT TIME
	TST (SP)+		;STOP THE WORLD
	BR GLPEN1

;GOBBLE IDLE BUFFER H -> FOR M.P.  RETURNS GB.PNT(H) IN D.

GLPBGB:	MOV #%GBMP,GB.STA(H)	;ACTIVATE AT M.P. LEVEL
	CLR GB.FF(H)		;INIT THE BUFFER
	CLR GB.NL(H)
	CLR GLPCOL		;START LINE IN COLUMN 0
	MOV H,D			;INIT INSERT POINTER
	ADD #GB.DAT,D
	MOV D,GB.PNT(H)
	MOV H,GLPLIM		;SET UP MAX. VALUE OF GB.PNT
	ADD #GB.LEN,GLPLIM
	RET

;GIVE BUFFER H -> TO P.I. LEVEL

GLPBWW:	BIT #1,D		;MUST BE EVEN NUMBER OF BYTES
	BEQ 1$
	CLRB (D)+

1$:	PUSH A			;INTERFACE GETS BYTES IN WRONG ORDER
	MOV P,A			;COMPUTE NUMBER OF WORDS IN LINE
	SUB H,A
	SUB #GB.DAT,A
	ASR A
	BNE 4$
	CLR (D)+		;CAN'T HAVE ZERO-LENGTH LINE
	INC A
4$:	MOV A,GB.PNT(H)		;SAVE WORD COUNT FOR P.I. LEVEL
2$:	SWAB -(D)
	SOB A,2$
	POP A
	TST GLPFIL		;IF STARTING NEW FILE,
	BNE 5$
	SETOM GLPFIL
	SETOM GB.FF(H)		; BE SURE TO GET NEW PAGE
5$:	MOV #%GBWRT,GB.STA(H)	;QUEUE TO P.I. LEVEL
	MOV GB.NXT(H),H		;ADVANCE TO NEXT BUFFER
	MOV H,GLPOIP
	MASK 6			;STOP P.I. LEVEL (HAVE TO LOCK OUT GLPBRK & CLKBRK)
	TST GLPOAC		;PRINTER ON?
	BNE 3$			;YUP
	MOV #%GCOFF,@#GLPCSR	;NO, CLEAR OLD STUFF IN INTERFACE
	TST GLPGF1		;AND PUT IN LOW-SPEED GRAPHIC MODE IF NECC	
	BEQ 6$
	MOV #%GCGRF,@#GLPCSR
	MOV #%GCLSL,@#GLPCSR	;LOW SPEED (COME ON, THIS IS ONLY A KL10!)
6$:	MOV #%GCON,@#GLPCSR	;TURN IT ON
	MOV #%GCION,@#GLPCSR	;TURN ON INTERRUPTS
	SETOM GLPOAC
;	PUSH @#PS		;FAKE AN INTERRUPT
;	CALL GLPBRK		;IS THIS NECESSARY?
3$:	UNMASK
	RET

;GOULD LPT VARIABLES

GLPCOL:	0		;CURRENT COLUMN NUMBER
GLPROW:	0		;CURRENT ROW NUMBER
 GLPRMX==67.		;NUMBER OF LINES PER PAGE
GLPLIM:	0		;ADDRESS OF END OF CURRENT BUFFER
GLPOAC:	0		;NON-ZERO => GOULD LPT P.I. ACTIVE
GLPGF1:	0		;NON-ZERO => GOULD LPT IN GRAPHIC MODE
GLIMBO:	0		;SAVE CHAR HERE WHEN RUN OUT OF BUFFERS
GLIMBF:	0		;NON-ZERO => CHAR IN GLIMBO
GLPFIL:	0		;NON-ZERO => IN MIDDLE OF A FILE
GLPTIM:	10.		;COUNT DOWN WHEN LOSING
GLPERR:	0		;NON-ZERO => ERROR STATUS FROM P.I.
.ENDC	;GOULDP

	.SBTTL SET LINE PARAMETERS

;LINE INDEX IN I
;DH11 PARAM REG IN A
;BUFFER SIZE IN B

SPARAM:	CMP I,#NFTTY
	BGE 1$
	 BPT
1$:	CMP I,#LASTTY
	BLE 2$
	 BPT
2$:	CMP B,#1.		;MINIMUM BUFFER SIZE ONE CHARACTER
	BGE 3$
	 MOV #1.,B
3$:	CMP B,#MAXBSZ		;MAXIMUM BUFFER SIZE <MAXBSZ> CHARACTERS
	BLE 4$
	 MOV #MAXBSZ,B
4$:	MOV B,BUFSIZ(I)		;SET AMOUNT OF BUFFER TO BE USED FROM NOW ON
	MOV HDWR(I),H		;(BUT NO LONGER DO WE ATTEMPT DYNAMIC BUFFER ALLOCATION)
	CMP H,#NLDHHX
	BHI 5$
	MASK 5			;LINE IS A DH11, HAVE TO SET LINE PARAM REG
	MOV DHLSEL(I),@DHSCR(H)	;SELECT THE LINE
	MOV A,@DHLPR(H)		;GIVE LINE-PARAMETER REG TO DH11
	UNMASK
5$:	MOV A,LPRVAL(I)		;STORE LPR IN CASE SOMEONE IS CURIOUS
	RET

	.SBTTL DH11 INPUT INTERRUPT

	.REPT NDHS
CONC DH,\.RPCNT+1,<IBK:	JSR H,DHIBK>
	  2*.RPCNT
.ENDR

DHIBK:	MOV (H),H			;PICK UP HARDWARE INDEX
	PUSH <A,B,I>
1$:	MOV @DHNRC(H),A			;RECIEVE A CHARACTER
	BPL DHIEX			;EXIT INTERRUPT IF NO MORE CHARS
	MOV A,I				;EXTRACT LINE NUMBER
	SWAB I
	BIC #177760,I
	ASL I
	ADD DHTYNO(H),I
.IFNZ NDHUN
	CMP I,#NLDHTY			;IGNORE NON-EXISTENT LINES
	BHI 1$
.ENDC
	CALL @TTYIPC(I)			;CALL LINE HACKER
	BR 1$				;AND CHECK FOR MORE

DHIEX:	POP <I,B,A,H>
	RTI

;NORMAL DH11 INPUT

DHNRMI:	BIT #%DXPAR,A
	BEQ 1$				;IGNORE IF PARITY ERROR
10$:	 RET
1$:	BIT #%DXBRK,A			;IF BREAK,
	BEQ RCV
	TST AUTOSP(I)			;AND LINE WANTS AUTOSPEED-ON-BREAK FEATURE
	BPL 10$
ASPMD:	MOV #DHASP,TTYIPC(I)		;PUT IT IN AUTOSPEED MODE
	MOV DHLSEL(I),@DHSCR(H)		;AND SET HARDWARE TO 300 BAUD
	MOV #016703,@DHLPR(H)
	RET

;CHAR IN A RECEIVED FROM LINE IN I
RCV:	BIC #177600,A			;7-BIT CHAR RECEIVE
RCV.FW:	TST NO.ITS			;ENTER HERE FOR FULL WORD RECEIVE
	BEQ 10$
21$:	MOV #DWNMSG,A			;ITS DOWN, GIVE MESSAGE
12$:	CALL GIVMSG
	RET

10$:	MOV #TYIRNG,B
	CMP RINGCT(B),#TYIRSZ-2
	BGT 11$
	CALL PUT			;FIRST PUT THE CHARACTER
	MOV I,A
	ASR A
	CALL PUT			;THEN THE TENNISH LINE NUMBER
	RET

11$:	MOV #IBOMSG,A			;INPUT BUFFER OVERFLOW
	BR 12$

.IFNZ NMPTYS		;HANDLE INPUT FROM THE MULTIPLEXOR LINE
MPXINP:	TST MPXENB
	BEQ RCV
	MOV MPXSEL,I			;CURRENT INPUT LINE
	TSTB A				;SPECIAL CHAR?
	BMI 1$
	JMP @TTYIPC(I)			;NO, RECEIVE ON APPROP LINE

1$:	MOV A,I				;SPECIAL CHAR, EXTRACT LINE#
	BIC #177700,I
;FOLLOWING FEATURE COMMENTED OUT SINCE IT CAUSES 11 TO LOOP
; WHEN NEXT INPUT ARRIVES -- NOT OBVIOUS HOW TO FIX.
;	CMP I,#77			;SELECT NON-MULTIPLEX INPUT?
;	BEQ 3$				;YES, DO SO
	ASL I
	ADD #NFMPTY,I
	CMP I,#LASTTY
	BHI 2$				;OUT OF RANGE, IGNORE
	MOV I,MPXSEL			;INPUT SELECT, SAVE LINE#
2$:	RET

3$:	MOV #MPXIDX,MPXSEL		;SELECT PASS THROUGH
	RET
.ENDC ;NMPTYS

;AUTOSPEED MODE COMES HERE WHEN CHAR RECIEVED

DHASP:	BIC #177600,A			;AUTOSPEED - SEE IF RECOGNIZE
	CMP A,#014
	BEQ 1$				;110 BAUD USUALLY GIVES THIS
	CMP A,#034
	BEQ 1$				;110 BAUD SOMETIMES GIVES THIS
	CMP A,#146
	BEQ 2$				;150 BAUD
	BIC #177640,A
	CMP A,#111
	BEQ 60$				;300/600
	BIC #177770,A
	CMP A,#5
	BEQ 3$				;300 BAUD
	RET				;SOMETHING ELSE, IGNORE

1$:	MOV #006307,A			;110 IN, 110 OUT, NO PARITY, 8 BITS, EXTRA STPBT
	MOV #5,B
	MOV #12200,-(SP)
	BR 10$

2$:	MOV #012503,A			;150 IN, 150 OUT, NO PARITY, 8 BITS
	MOV #7,B
	MOV #13300,-(SP)
	BR 10$

3$:	MOV #016703,A			;300 IN, 300 OUT, NO PARITY, 8 BITS
	MOV #15.,B
	MOV #14400,-(SP)
	BR 10$

60$:	MOV #020703,A			;300 IN, 600 OUT, NO PARITY, 8 BITS
	MOV #30.,B
	MOV #14100,-(SP)
	BR 10$

10$:	CALL SPARAM			;SET BUFFER SIZE AND HARDWARE SPEED
	MOV I,A				;SET UP SET-SPEED COMMAND TO -10
	ASR A
	BIS (SP)+,A
	TST TTYHNG(I)			;IF THIS IS NEW STATUS FOR 10,
	BNE 11$
	INC HNGSIG			;INDICATE STATUS WAITING
11$:	MOV A,TTYHNG(I)			;SAVE THIS LINE'S LATEST STATUS
	MOV #ASPACK,A			;ACKNOWLEDGE TO USER THAT HE WON
	CALL GIVMSG
	MOV NRMIPC(I),TTYIPC(I)		;AND TAKE LINE OUT OF AUTOSPEED MODE
;	MOV #32,A			;NOW SEND IN A CONTROL/Z
;	BR RCV
; PRECEDING TWO LINES COMMENTED OUT SO ITS GREETING
; MESSAGE WON'T CANCEL -11 GREETING MESSAGE
; WHEN OPERATING AT 110 BAUD.
	RET

	.SBTTL DH11 OUTPUT INTERRUPTS

.REPT NDHS
CONC DH,\.RPCNT+1,<OBK:	JSR H,DHOBK>
	  2*.RPCNT
.ENDR

DHOBK:	MOV (H),H			;GET HARDWARE UNIT NUMBER
	BIT #DHSNXM,@DHSCR(H)		;IS THIS INTERRUPT DUE TO NXM?
	BEQ 1$
	 BPT				;YES
1$:	BIC #DHTDON,@DHSCR(H)		;HARDWARE KLUDGE TO MAKE INTERRUPTS WIN
	PUSH <A,B,C,I>
	MOV DHOAC(H),C			;SEE WHICH BAR BITS HAVE TURNED OFF
	BIC @DHBAR(H),C
	BIC C,DHOAC(H)
	MOV DHTYNO(H),I
	ADD #15.*2,I
2$:	BIT DHLBIT(I),C
	BEQ 4$
.IFNZ NMPTYS
	CMP I,#MPXIDX
	BNE 3$
	CALL MPXDON
.ENDC ;NMPTYS
3$:
.IFNZ NDHUN
	CMP I,#NLDHTY			;IGNORE NON-EXISTENT LINES
	BHI 4$
.ENDC
	CALL XMTDON
4$:	SUB #2,I
	CMP I,DHTYNO(H)
	BGE 2$
DHOEX:	POP <I,C,B,A,H>
	RTI

XMTDON:	TST TYPING(I)		;HERE WHEN OUTPUT FINISHES
	BEQ 1$			;BRANCH IF -10 DOESN'T WANT TO KNOW ABOUT IT
	MOV I,A
	ASR A			;PUT TENNISH LINE NUMBER INTO RING
	MOV #TYORNG,B		;MAIN PROG LEVEL WILL LATER TELL -10
	CALL PUT
1$:	CLR TYPING(I)
	RET

.IFNZ NMPTYS	;OUTPUT DONE ON MULTIPLEXED LINE
MPXDON:	PUSH <C,D,H,I>
	TST MPXOAC
	BGE 1$
	NEG MPXOAC	;SENT HEADER, NOW SEND DATA
	MOV MPXOLN,A
	MOV MPXPNT(A),D
	MOV MPXNBT(A),C
	CLR MPXNBT(A)
	CALL @STROUT(H)	
	BR 9$

1$:	MOV MPXOLN,I	;OUTPUT IS DONE ON THAT LINE NOW
	ADD #NFMPTY,I
	CALL XMTDON
	CLR MPXOAC	;MPX IDLE
	CALL STRMPX	;LOOK FOR NEW STUFF TO DO
9$:	POP <I,H,D,C>
	RET
.ENDC ;NMPTYS

	.SBTTL DL11 INTERRUPTS

.REPT NDLS
CONC DL,\.RPCNT+1,<IBK: JSR H,DLIBK>
	NFDLHX+<2*.RPCNT>
CONC DL,\.RPCNT+1,<OBK: JSR H,DLOBK>
	NFDLHX+<2*.RPCNT>
.ENDR

DLIBK:	MOV (H),H		;GET HARDWARE INDEX OF INTERRUPTING UNIT
	PUSH <A,B,I>
	MOV @DLKB(H),A		;GET RECEIVED CHARACTER
	MOV DLTYNO(H),I		;GET LINE NUMBER RECEIVED ON
.IFNZ DTE20P
	BNE 2$			;ONLY T00 CAN RETURN TO KLDCP
	BIT #20000,A		;IF BREAK KEY IS HIT
	BEQ 1$
	SETOM KLDCPF		;USER WANTS TO RETURN TO KLDCP
	BR DLBKEX		;FOR ONE COMMAND LINE

1$:	TST DDTMOD		;IF IN DDT MODE,
	BEQ 2$
	BIC #-200,A		; HANDLE INPUT DIFFERENTLY
	MOV A,DDTCHR
	BR DLBKEX

2$:
.ENDC ;DTE20P
	CALL @TTYIPC(I)
DLBKEX:	POP <I,B,A,H>
	RTI

DLOBK:	MOV (H),H		;GET HARDWARE INDEX OF INTERRUPTING UNIT
	TST DLOAC(H)
	BEQ DLBKX1		;NOT SUPPOSED TO BE TYPING OUT, IGNORE INT
	DEC DLBC(H)		;GOT ANY MORE CHARACTERS?
	BLT DLBKX2		;NO, GO GIVE OUTPUT DONE
	MOV DLCA(H),-(SP)	;YES, GIVE NEXT CHARACTER
	MOVB @(SP)+,@DLPB(H)
	INC DLCA(H)
DLBKX1:	POP H
	RTI

DLBKX2:	PUSH <A,B,I>		;OUTPUT DONE
	MOV DLTYNO(H),I		;GET TTY INDEX OF INTERRUPTING LINE
	CLR DLOAC(H)		;OUTPUT NO LONGER ACTIVE ON THIS LINE
	CALL XMTDON
	BR DLBKEX

	.SBTTL CLOCK INTERRUPT

CLKBRK:	SETOM WAKE		;WAKE UP MAIN LOOP
.IFNZ GOULDP
	PUSH @#PS		;CHECK GOULD LPT
	CALL GLPBRK		;(LOSES INTERRUPTS)
	DEC GLPTIM		;TIME TO CHECK GOULD LPT?
	BGT 13$			;NOT YET
	MOV #10.*60.,GLPTIM
	BIT #%GSNRD,@#GLPCSR	;YES, LOSING?
	BNE 14$			;PROBABLY
	CLR GLPERR		;PROBABLY NOT
	BR 13$			;(CAN'T TELL FOR SURE IF %GCON NOT DONE)

14$:	MOV @#GLPCSR,GLPERR	;LPT LOSING, TELL 10
	CALL GLPRST		;AND MAKE SURE BUFFERS DON'T CHOKE UP
.ENDC ;GOULDP
13$:	PUSH <A,B,I>		;CHECK FOR HANGUPS
	MOV #NFTTY,I
16$:	TST DIALED(I)		;HANGUP IN PROGRESS ON THIS LINE?
	BPL 17$			;NO
	INC DIALED(I)		;YES, TIMED OUT?
	BMI 17$
	CLR DIALED(I)		;YUP, LINE IS HUNG UP
	MOV I,A			;TELL -10 ABOUT IT
	ASR A
	TST TTYHNG(I)		;IF THIS IS NEW STATUS FOR 10,
	BNE 18$
	INC HNGSIG		;INDICATE STATUS WAITING
18$:	MOV A,TTYHNG(I)		;SAVE THIS LINE'S LATEST STATUS
17$:	ADD #2,I
	CMP I,#LASTTY
	BLO 16$
	POP <I,B,A>

	ROR SWR			;LOW BIT OF SWITCHES => DDT
	BCC CLKEX
	BPT
CLKEX:	RTI
.IFNZ MDMP
	.SBTTL MODEM CONTROL

MDMBRK:	PUSH <A,B,I,H>
	MOV MDMCSR,I			;GET ASSOCIATED TTY INDEX
	BIC #177760,I
	ASL I
	MOV M2LMAP(I),I
	BEQ 90$				;EXIT IF THIS LINE NOT UNDER MODEM CONTROL
;	TST MDMCSR	.SEE MDMRNG
;	BPL 10$
;	TST DIALED(I)			;RINGING.  IS LINE DIALED UP ALREADY?
;	BNE 10$				;YES, NOT SUPPOSED TO BE RINGING
;	MOV #LINENB+LINDTR,MDMLSR	;ANSWER THE PHONE

10$:	BIT #LINCTS,MDMLSR		;DO WE HAVE CLEAR-TO-SEND?
	BEQ 20$				;NO
	TST DIALED(I)			;YES, WHAT WAS PREVIOUS STATE?
	BEQ 13$				;WAS OFF, THIS IS A DIALUP
	BPL 90$				;WAS ON, IGNORE
	NEG DIALED(I)			;WAS HANGING UP, ABORT IT
	BR 90$

13$:	INC DIALED(I)			;LINE IS NOW DIALED UP
	TST MDMINI			;IF GETTING INITIAL STATE,
	BNE 90$				;DON'T HACK AUTOSPEED
	TST AUTOSP(I)			;IF IT HAS AUTOSPEED,
	BEQ 90$
	MOV HDWR(I),H			;HACK THAT
	CALL ASPMD
	BR 90$

20$:	TST DIALED(I)			;CTS DROPPED
	BMI 90$				;ALREADY KNOWN ABOUT, IGNORE
	MOV #-HNGDLY,DIALED(I)		;OTHERWISE START HANGUP TIMEOUT

90$:	BIC #MDMDON,MDMCSR		;RESTART SCANNER
	POP <H,I,B,A>
	RTI
.ENDC ;MDMP

.IFNZ GOULDP
.SBTTL GOULD PRINTER P.I. LEVEL

GLPBRK:	BIT #%GSBSY,@#GLPCSR
	BEQ 1$
	RTI				;LPT BUSY, WAIT

1$:	BIT #%GSDON,@#GLPCSR
	BNE 2$
	RTI				;LPT BUSY OTHER FLAVOR

2$:	PUSH <A,B,H>
	BIT #%GSERR,@#GLPCSR		;LPT LOSING?
	BEQ GLPBR1
	CALL GLPRST			;YUP, RESET THE BUFFERS
	MOV @#GLPCSR,GLPERR		;AND TELL 10

GLPOFF:	CLR GLPOAC			;HERE TO STOP P.I.
	MOV #%GCIOF,@#GLPCSR
	MOV #5000.,A			;LPT SOMETIMES BUSY FOR A WHILE
1$:	BIT #%GSBSY,@#GLPCSR		;HAVE TO WAIT SO TONER PUMPS WILL
	BEQ 2$				;REALLY TURN OFF
	SOB A,1$
2$:	MOV #%GCOFF,@#GLPCSR
GLPEX:	POP <H,B,A>
	RTI

GLPFIN:	MOV #%GBIDL,GB.STA(H)		;DONE WITH THIS BUFFER
	MOV GB.NXT(H),H			;CHECK NEXT
	MOV H,GLPOOP

GLPBR1:	MOV GLPOOP,H			;CHECK ON BUFFERS
	CMP GB.STA(H),#%GBDMA		;FINISH DMA XFER?
	BEQ GLPFIN			;YES
	CMP GB.STA(H),#%GBWRT		;QUEUED OR ALREADY ACTIVE AT P.I.?
	BLT GLPOFF			;NO, STOP
	MOV #%GBPI,GB.STA(H)		;YES, ACTIVATE IT AT P.I.
	TST GB.FF(H)			;NEED FF?
	BEQ 1$
	MOV #%GCFF,@#GLPCSR		;YES
	CLR GB.FF(H)
	BR GLPEX

1$:	TST GB.NL(H)			;NEED BLANK LINES?
	BEQ 2$
	DEC GB.NL(H)			;YES, GIVE ONE
	MOV #%GCADV,@#GLPCSR
	BR GLPEX

2$:	MOV H,B				;SET UP TEXT ADDR
	ADD #GB.DAT,B
	MOV GB.PNT(H),A			;SET UP TEXT WORD COUNT
	NEG A
	MOV A,@#GLPWC
	MOV B,@#GLPCA			;START XFER
	MOV #%GBDMA,GB.STA(H)		;FLAG BUFFER ACTIVE AT DMA LEVEL
	BR GLPEX

GLPRST:	PUSH H
	MOV #GLPBFF,H			;FLUSH ALL BUFFERS
	MOV H,GLPOOP
	MOV H,GLPOIP
3$:	CLR (H)+
	MOV (H),H
	CMP H,#GLPBFF
	BNE 3$
	MOV #60.*10.,GLPTIM		;SET TIMEOUT
	POP H
	RET

.ENDC ;GOULDP

	.SBTTL ETHERNET STUFF

;START ETHERNET INPUT TRANSFER

ETHISR:	BPT		;NOT WRITTEN YET

;START ETHERNET OUTPUT TRANSFER

ETHOSR:	BPT		;NOT WRITTEN YET

;FINISH ETHERNET INPUT TRANSFER

ETHIFN:	BPT		;NOT WRITTEN YET

;FINISH ETHERNET OUTPUT TRANSFER

ETHOFN:	BPT		;NOT WRITTEN YET
.IFNZ DL10P
	.SBTTL TRAP HANDLING

TRAP14:	HALT			;BPT WITH NO RUG IN CORE

TRAP10:	BPT			;ILLEGAL INSTRUCTION

TRAP4:	NOP			;PATCH BPT HERE IF YOU WANT
	CMP (SP),#MAIN		;IF TRAP4 IN MAIN LOOP...
	BLO CRASH
	CMP (SP),#MAINE
	BHIS CRASH
	BIT #DLXPRT,DLXCSR	;AND DL10 PORT TURNED OFF
	BNE CRASH
	TST DLXOFF		;AND WE THOUGHT IT WAS ON
	BNE CRASH
RESTRT:	MOV #STKBAS,SP		;THEN RESTART MAIN LOOP
	CLR -(SP)		;WHICH WILL WAIT FOR DL10 PORT TO TURN ON
	MOV #MAIN,-(SP)
	RTI

CRASH:	BPT			;OTHERWISE, CRASH

PWRFAL:	RESET			;POWER FAIL OR UP - IF FAIL, HALT DURING RESET
1$:	MOV #20,B		;WAIT 2 SECONDS TO
	CLR A			; MAKE SURE POWER IS REALLY ON
	SOB A,.
	SOB B,1$
	SETOM DLXOFF
	SETOM NO.ITS
	JMP INIT		;POWER SEEMS UP, RESTART PROGRAM
.ENDC ;DL10P

	.SBTTL INITIALIZATION
GO::
INIT:	CLR PS
.IFNZ DL10P
	RESET
	MOV #STKBAS,SP
	TST 14
	BNE 1$			;BPT ALREADY SET UP BY RUG
	MOV #TRAP14,14
	MOV #340,16
1$:
.ENDC ;DL10P

	MOV #NFTTY,I
76$:	MOV NRMIPC(I),TTYIPC(I)
	ADD #2,I
	CMP I,#LASTTY
	BLE 76$
.IFNZ MDMP
;TURN ON DM11-BB
	MOV #MDMCLR+MDMCSN,MDMCSR	;CLEAR SCANNER MEMORY
2$:	BIT #MDMBSY,MDMCSR
	BNE 2$
	CLR I
	CLR A
3$:	TST M2LMAP(I)			;TURN ON CONNECTED MODEM CHANNELS
	BEQ 4$
	MOV A,MDMCSR
	MOV #LINENB,MDMLSR
4$:	TST (I)+
	INC A
	CMP A,#16.
	BLT 3$
	SETOM MDMINI			;TREAT FIRST-TIME INTERRUPTS DIFFERENTLY
	MOV #MDMSCN+MDMIEN,MDMCSR	;ENABLE SCANNER INTERRUPTS
	MOV #20000.,A
	SOB A,.				;DELAY 50 MILLISECONDS
	CLR MDMINI			;WHILE P.I. LEVEL GETS INITIAL STATUS
.ENDC ;MDMP

.IFG NDHS
;TURN ON DH11'S
	MOV #NLDHHX,H
20$:	MOV #DHRENB+DHTENB,@DHSCR(H)
	SUB #2,H
	BGE 20$
.ENDC ;NDHS

;TURN ON DL11S
.IFG NDLS
	MOV #NLDLHX,H
	MOV #NDLS-1,A
21$:
.IIF NZ DTE20P, BEQ 22$		;NO KBD INT ON KL10 CTY DUE TO KLDCP LOSSAGE
	MOV #103,@DLKS(H)	;ACTIVATE KEYBOARD INTERRUPT, D.T.R., READER
22$:	MOV #100,@DLPS(H)	;ACTIVATE PRINTER INTERRUPT
	SUB #2,H
	DEC A
	BPL 21$

;SET LINE PARAMETERS AND ALLOCATE BUFFERS
	MOV #NFTTY,I
10$:	MOV LPRVAL(I),A
	MOV BUFSIZ(I),B
	CALL SPARAM
	ADD #2,I
	CMP I,#LASTTY
	BLE 10$

;TURN ON CLOCK
.IIF Z DTE20P,	MOV #100,@#LKS	;NO CLOCK INTERRUPTS IF KLDCP IS HACKING CLOCK TOO

.IFNZ DTE20P
;INITIALIZE DTE20
	MOV #37774,DLYCNT	;DMA TO BANK 0, 2 USEC DELAY
	MOV #%D3BYT,DIAG3	;DO TO10 TRANSFERS IN BYTE MODE
	MOV #MAIN,SADR		;ONLY DO INIT ONCE
.ENDC ;DTE20P
;GO
	JMP MAIN

.IFNZ GOULDP
.SBTTL GOULD PRINTER BUFFERS

GLPOIP:	GLPBFF		;NEXT BUFFER IN AT M.P. LEVEL
GLPOOP:	GLPBFF		;NEXT BUFFER OUT AT P.I. LEVEL

	.REPT NGLPBF	;ASSEMBLE THE BUFFERS
	0		.SEE GB.STA
	GLPBFF		;DUE TO PALX BUG, LEAVE .SEE ON NEXT LINE
			.SEE GB.NXT
GLPBFF==.-4
	0		.SEE GB.FF
	0		.SEE GB.NL
	0		.SEE GB.PNT
	.BLKB GLPBSZ
	.ENDR
.ENDC	;GOULDP

	.SBTTL "TTYTYP" PARAMETER FILE

T LPRVAL:
	.BLKW NCT		;DH11 PARAMETER REG

BUFFRS:	;BEGIN ALLOCATING BUFFERS HERE

INFORM <BEGINNING OF BUFFERS = >,\BUFFRS
INFORM <HIGHEST LOCATION USED = >,\BUFFRS+<NCT*MAXBSZ>,< (>,\<BUFFRS+<NCT*MAXBSZ>+3777>/4000,<K)>
	
.IF P2			;SPEED UP THE ASSEMBLY
OFF==69105	;KLUDGES SO I DON'T HAVE TO PUT KEYWORD PARAMETERS INTO PALX
40K==40000
80K==80000

.MACRO SPEED BAUD
ZZ==-1
.IIF EQ BAUD-OFF,  ZZ==0
.IIF EQ BAUD-50,   ZZ==1
.IIF EQ BAUD-75,   ZZ==2
.IIF EQ BAUD-110,  ZZ==3
.IIF EQ BAUD-134,  ZZ==4
.IIF EQ BAUD-150,  ZZ==5
.IIF EQ BAUD-200,  ZZ==6
.IIF EQ BAUD-300,  ZZ==7
.IIF EQ BAUD-600,  ZZ==10
.IIF EQ BAUD-1200, ZZ==11
.IIF EQ BAUD-1800, ZZ==12
.IIF EQ BAUD-2400, ZZ==13
.IIF EQ BAUD-4800, ZZ==14
.IIF EQ BAUD-9600, ZZ==15
.IIF EQ BAUD-80K, ZZ==16
.IIF EQ BAUD-40K, ZZ==17
.IIF LT ZZ, .ERROR UNRECOGNIZED SPEED "BAUD"
.ENDM SPEED

.MACRO IPARM N,ODFLT,IDFLT,MUMLST
.IF GE <2*N>-NFTTY
.IF LE <2*N>-LASTTY
%%.ISPEED==-1
%%.SPEED==-1
.IRP MUM,<MUMLST>
.IF NB <MUM>
 ZZ==0
 .IRPC MUMB,<MUM>
  .IIF GE .IRPCNT-2, .MEXIT
  .IIF IDN MUMB,S, .IIF EQ .IRPCNT, ZZ==1
  .IIF IDN MUMB,P, .IIF EQ .IRPCNT-1, ZZ==ZZ+1
  .IIF IDN MUMB,I, .IIF EQ .IRPCNT, ZZ==1
  .IIF IDN MUMB,S, .IIF EQ .IRPCNT-1, ZZ==ZZ+1
  .ENDM
 .IIF EQ ZZ-2, %%.'MUM
 .ENDC
.ENDM
.IF LT %%.ISPEED
 .IIF LT %%.SPEED, %%.ISPEED==IDFLT
 .IELSE %%.ISPEED==%%.SPEED
.ENDC
.IIF LT %%.SPEED, %%.SPEED==ODFLT
SPEED %%.ISPEED
IZZ==ZZ
SPEED %%.SPEED
; BUFFER SIZE IS 1/2 SECOND'S TYPING
; BUT WILL BE SUBJECT TO LIMIT OF MAXBSZ
.IIF LT ZZ-7, BZZ==5.
.IIF EQ ZZ-7, BZZ==15.
.IIF EQ ZZ-10, BZZ==30.
.IIF EQ ZZ-11, BZZ==60.
.IIF EQ ZZ-12, BZZ==90.
.IIF EQ ZZ-13, BZZ==120.
.IIF EQ ZZ-14, BZZ==240.
.IIF EQ ZZ-15, BZZ==480.
.IIF GT ZZ-15, BZZ==1000.
.=LPRVAL+<2*N>		;ASSEMBLE LINE PARAMETER WORD
.IIF NE ZZ-3, <ZZ*2000>+<IZZ*100>+3	;ISPEED, OSPEED, NO PARITY, 8 BITS, FULL DUPLEX
.IELSE <ZZ*2000>+<IZZ*100>+3+4		;110 BAUD EXTRA STOP BIT
.=BUFSIZ+<2*N>
BZZ			;ASSEMBLE BUFFER SIZE
.ENDC
.ENDC
.ENDM IPARM

;MACROS USED IN THE TTYTYP FILE:

.MACRO TTDPRT TN,A,B,C,D,E,F,G,H,I,J
IPARM TN,300,300,<A,B,C,D,E,F,G,H,I,J>
.ENDM TTDPRT

.MACRO TTDMRX TN,A,B,C,D,E,F,G,H,I,J
IPARM TN,600,600,<A,B,C,D,E,F,G,H,I,J>
.ENDM TTDMRX

.MACRO TTDTRM TN,A,B,C,D,E,F,G,H,I,J
IPARM TN,1200,1200,<A,B,C,D,E,F,G,H,I,J>
.ENDM TTDTRM

.MACRO TTDLPT TN,A,B,C,D,E,F,G,H,I,J
IPARM TN,9600,9600,<A,B,C,D,E,F,G,H,I,J>
.ENDM TTDLPT

.MACRO TTDLA36 TN,A,B,C,D,E,F,G,H,I,J
IPARM TN,300,300,<A,B,C,D,E,F,G,H,I,J>
.ENDM TTDLA36

.MACRO TTDIML TN,A,B,C,D,E,F,G,H,I,J
IPARM TN,50K,25K,<A,B,C,D,E,F,G,H,I,J>
.ENDM TTDIML

.MACRO TTDVT TN,A,B,C,D,E,F,G,H,I,J
IPARM TN,9600,9600,<A,B,C,D,E,F,G,H,I,J>
.ENDM TTDVT

.MACRO TTDTEK TN,A,B,C,D,E,F,G,H,I,J
IPARM TN,1200,1200,<A,B,C,D,E,F,G,H,I,J>
.ENDM TTDTEK

.MACRO TTDLSR TN,A,B,C,D,E,F,G,H,I,J
IPARM TN,2400,2400,<A,B,C,D,E,F,G,H,I,J>
.ENDM TTDLSR

.MACRO TTDDPT TN,A,B,C,D,E,F,G,H,I,J
IPARM TN,2400,2400,<A,B,C,D,E,F,G,H,I,J>
.ENDM TTDDPT

.MACRO TTDGT40 TN,A,B,C,D,E,F,G,H,I,J
IPARM TN,4800,4800,<A,B,C,D,E,F,G,H,I,J>
.ENDM TTDGT40

.MACRO TTD11 TN,A,B,C,D,E,F,G,H,I,J
IPARM TN,4800,4800,<A,B,C,D,E,F,G,H,I,J>
.ENDM TTD11

.MACRO TTDRAN TN,A,B,C,D,E,F,G,H,I,J
IPARM TN,FOO,FOO,<A,B,C,D,E,F,G,H,I,J>
.ENDM TTDRAN

.MACRO TTDTV TN,A,B,C,D,E,F,G,H,I,J
IPARM TN,FOO,FOO,<A,B,C,D,E,F,G,H,I,J>
.ENDM TTDTV

.MACRO TTDGRN TN,A,B,C,D,E,F,G,H,I,J
IPARM TN,9600,9600,<A,B,C,D,E,F,G,H,I,J>
.ENDM TTDGRN

.MACRO TTDSTY TN,A,B,C,D,E,F,G,H,I,J
IPARM TN,FOO,FOO,<A,B,C,D,E,F,G,H,I,J>
.ENDM TTDSTY

.MACRO REPEAT N,FOO
FAKOUT:	.REPT N
FAKOUT===0
.ENDM

NSTTYS==0			;WE'RE NOT INTERESTED IN PSEUDO-TTYS
N11TYS==0			;NOR IN PDP11 TVS

.INSRT SYSTEM;TTYTYP >

;EXPUNGE
OFF===0
40K===0
80K===0
%%.ISPEED===0
%%.SPEED===0
ZZ===0
IZZ===0
BZZ===0

.ENDC ;P2

.END INIT
βββ